<commit_before>/*
Copyright 2017 Google Inc.

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

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

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

// Package grpcvtctlclient contains the gRPC version of the vtctl client protocol
package grpcvtctlclient

import (
	"flag"
	"time"

	"github.com/youtube/vitess/go/vt/grpcclient"
	"github.com/youtube/vitess/go/vt/logutil"
	"github.com/youtube/vitess/go/vt/vtctl/vtctlclient"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	logutilpb "github.com/youtube/vitess/go/vt/proto/logutil"
	vtctldatapb "github.com/youtube/vitess/go/vt/proto/vtctldata"
	vtctlservicepb "github.com/youtube/vitess/go/vt/proto/vtctlservice"
)

var (
	cert = flag.String("vtctld_grpc_cert", "", "the cert to use to connect")
	key  = flag.String("vtctld_grpc_key", "", "the key to use to connect")
	ca   = flag.String("vtctld_grpc_ca", "", "the server ca to use to validate servers when connecting")
	name = flag.String("vtctld_grpc_server_name", "", "the server name to use to validate server certificate")
)

type gRPCVtctlClient struct {
	cc *grpc.ClientConn
	c  vtctlservicepb.VtctlClient
}

func gRPCVtctlClientFactory(addr string) (vtctlclient.VtctlClient, error) {
	opt, err := grpcclient.SecureDialOption(*cert, *key, *ca, *name)
	if err != nil {
		return nil, err
	}
	opts := []grpc.DialOption{opt, grpc.WithTimeout(dialTimeout)}
	if err != nil {
		return nil, err
	}

	// create the RPC client
	cc, err := grpcclient.Dial(addr, grpcclient.FailFast(false), opt)
	if err != nil {
		return nil, err
	}
	c := vtctlservicepb.NewVtctlClient(cc)

	return &gRPCVtctlClient{
		cc: cc,
		c:  c,
	}, nil
}

type eventStreamAdapter struct {
	stream vtctlservicepb.Vtctl_ExecuteVtctlCommandClient
}

func (e *eventStreamAdapter) Recv() (*logutilpb.Event, error) {
	le, err := e.stream.Recv()
	if err != nil {
		return nil, err
	}
	return le.Event, nil
}

// ExecuteVtctlCommand is part of the VtctlClient interface
func (client *gRPCVtctlClient) ExecuteVtctlCommand(ctx context.Context, args []string, actionTimeout time.Duration) (logutil.EventStream, error) {
	query := &vtctldatapb.ExecuteVtctlCommandRequest{
		Args:          args,
		ActionTimeout: int64(actionTimeout.Nanoseconds()),
	}

	stream, err := client.c.ExecuteVtctlCommand(ctx, query)
	if err != nil {
		return nil, err
	}
	return &eventStreamAdapter{stream}, nil
}

// Close is part of the VtctlClient interface
func (client *gRPCVtctlClient) Close() {
	client.cc.Close()
}

func init() {
	vtctlclient.RegisterFactory("grpc", gRPCVtctlClientFactory)
}
<commit_msg>Remove deprecated DialTimeout<commit_after>/*
Copyright 2017 Google Inc.

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

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

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

// Package grpcvtctlclient contains the gRPC version of the vtctl client protocol
package grpcvtctlclient

import (
	"flag"
	"time"

	"github.com/youtube/vitess/go/vt/grpcclient"
	"github.com/youtube/vitess/go/vt/logutil"
	"github.com/youtube/vitess/go/vt/vtctl/vtctlclient"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	logutilpb "github.com/youtube/vitess/go/vt/proto/logutil"
	vtctldatapb "github.com/youtube/vitess/go/vt/proto/vtctldata"
	vtctlservicepb "github.com/youtube/vitess/go/vt/proto/vtctlservice"
)

var (
	cert = flag.String("vtctld_grpc_cert", "", "the cert to use to connect")
	key  = flag.String("vtctld_grpc_key", "", "the key to use to connect")
	ca   = flag.String("vtctld_grpc_ca", "", "the server ca to use to validate servers when connecting")
	name = flag.String("vtctld_grpc_server_name", "", "the server name to use to validate server certificate")
)

type gRPCVtctlClient struct {
	cc *grpc.ClientConn
	c  vtctlservicepb.VtctlClient
}

func gRPCVtctlClientFactory(addr string) (vtctlclient.VtctlClient, error) {
	opt, err := grpcclient.SecureDialOption(*cert, *key, *ca, *name)
	if err != nil {
		return nil, err
	}
	// create the RPC client
	cc, err := grpcclient.Dial(addr, grpcclient.FailFast(false), opt)
	if err != nil {
		return nil, err
	}
	c := vtctlservicepb.NewVtctlClient(cc)

	return &gRPCVtctlClient{
		cc: cc,
		c:  c,
	}, nil
}

type eventStreamAdapter struct {
	stream vtctlservicepb.Vtctl_ExecuteVtctlCommandClient
}

func (e *eventStreamAdapter) Recv() (*logutilpb.Event, error) {
	le, err := e.stream.Recv()
	if err != nil {
		return nil, err
	}
	return le.Event, nil
}

// ExecuteVtctlCommand is part of the VtctlClient interface
func (client *gRPCVtctlClient) ExecuteVtctlCommand(ctx context.Context, args []string, actionTimeout time.Duration) (logutil.EventStream, error) {
	query := &vtctldatapb.ExecuteVtctlCommandRequest{
		Args:          args,
		ActionTimeout: int64(actionTimeout.Nanoseconds()),
	}

	stream, err := client.c.ExecuteVtctlCommand(ctx, query)
	if err != nil {
		return nil, err
	}
	return &eventStreamAdapter{stream}, nil
}

// Close is part of the VtctlClient interface
func (client *gRPCVtctlClient) Close() {
	client.cc.Close()
}

func init() {
	vtctlclient.RegisterFactory("grpc", gRPCVtctlClientFactory)
}
<|endoftext|>


<commit_before>package utils

import (
	"strings"
	"fmt"
	"strconv"
	"github.com/jfrogdev/jfrog-cli-go/utils/cliutils"
	"github.com/jfrogdev/jfrog-cli-go/utils/ioutils"
	"github.com/jfrogdev/jfrog-cli-go/utils/config"
	"github.com/jfrogdev/jfrog-cli-go/utils/cliutils/logger"
)

const (
	MOVE MoveType = "move"
	COPY MoveType = "copy"
)

func MoveFilesWrapper(moveSpec *SpecFiles, flags *MoveFlags, moveType MoveType) (err error) {
	PreCommandSetup(flags)
	for i := 0; i < len(moveSpec.Files); i++ {
		switch moveSpec.Get(i).GetSpecType() {
		case WILDCARD:
			err = moveWildcard(moveSpec.Get(i), flags, moveType)
		case SIMPLE:
			err = moveSimple(moveSpec.Get(i), flags, moveType)
		case AQL:
			err = moveAql(moveSpec.Get(i), flags, moveType)
		}
		if err != nil {
			return
		}
	}
	return
}

func moveAql(fileSpec *Files, flags *MoveFlags, moveType MoveType) error {
	resultItems, err := AqlSearchBySpec(fileSpec.Aql, flags)
	if err != nil {
		return err
	}
	return moveFiles("", resultItems, fileSpec, flags, moveType)
}

func moveWildcard(fileSpec *Files, flags *MoveFlags, moveType MoveType) error {
	isRecursive, err := cliutils.StringToBool(fileSpec.Recursive, true)
	if err != nil {
		return err
	}
	resultItems, err := AqlSearchDefaultReturnFields(fileSpec.Pattern, isRecursive, fileSpec.Props, flags)
	if err != nil {
		return err
	}
	regexpPath := cliutils.PathToRegExp(fileSpec.Pattern)
	return moveFiles(regexpPath, resultItems, fileSpec, flags, moveType)
}

func moveSimple(fileSpec *Files, flags *MoveFlags, moveType MoveType) error {

	cleanPattern := cliutils.StripChars(fileSpec.Pattern, "()")
	patternFileName, _ := ioutils.GetFileAndDirFromPath(fileSpec.Pattern)

	regexpPattern := cliutils.PathToRegExp(fileSpec.Pattern)
	placeHolderTarget, err := cliutils.ReformatRegexp(regexpPattern, cleanPattern, fileSpec.Target)
	if err != nil {
		return err
	}

	if strings.HasSuffix(placeHolderTarget, "/") {
		placeHolderTarget += patternFileName
	}
	_, err = moveFile(cleanPattern, placeHolderTarget, flags, moveType)
	return err
}

func moveFiles(regexpPath string, resultItems []AqlSearchResultItem, fileSpec *Files, flags *MoveFlags, moveType MoveType) error {
	movedCount := 0

	for _, v := range resultItems {
		destPathLocal := fileSpec.Target
		isFlat, err := cliutils.StringToBool(fileSpec.Recursive, true)
		if err != nil {
			return err
		}
		if !isFlat {
			if strings.Contains(destPathLocal, "/") {
				file, dir := ioutils.GetFileAndDirFromPath(destPathLocal)
				destPathLocal = cliutils.TrimPath(dir + "/" + v.Path + "/" + file)
			} else {
				destPathLocal = cliutils.TrimPath(destPathLocal + "/" + v.Path + "/")
			}
		}
		destFile, err := cliutils.ReformatRegexp(regexpPath, v.GetFullUrl(), destPathLocal)
		if err != nil {
			return err
		}
		if strings.HasSuffix(destFile, "/") {
			destFile += v.Name
		}
		success, err := moveFile(v.GetFullUrl(), destFile, flags, moveType)
		if err != nil {
			return err
		}
		movedCount += cliutils.Bool2Int(success)
	}

	logger.Logger.Info(moveMsgs[moveType].MovedMsg + " " + strconv.Itoa(movedCount) + " artifacts in Artifactory")
	return nil
}

func moveFile(sourcePath, destPath string, flags *MoveFlags, moveType MoveType) (bool, error) {
	message := moveMsgs[moveType].MovingMsg + " artifact: " + sourcePath + " to " + destPath
	if flags.DryRun == true {
		fmt.Println("[Dry run] " + message)
		return true, nil
	}

	logger.Logger.Info(message)

	moveUrl := flags.ArtDetails.Url
	restApi := "api/" + string(moveType) + "/" + sourcePath
	requestFullUrl, err := BuildArtifactoryUrl(moveUrl, restApi, map[string]string{"to": destPath})
	if err != nil {
		return false, err
	}
	httpClientsDetails := GetArtifactoryHttpClientDetails(flags.ArtDetails)
	resp, _, err := ioutils.SendPost(requestFullUrl, nil, httpClientsDetails)
	if err != nil {
		return false, err
	}

	logger.Logger.Info("Artifactory response:", resp.Status)
	return resp.StatusCode == 200, nil
}

var moveMsgs = map[MoveType]MoveOptions{
	MOVE: MoveOptions{MovingMsg: "Moving", MovedMsg: "Moved"},
	COPY: MoveOptions{MovingMsg: "Copying", MovedMsg: "Copied"},
}

type MoveOptions struct {
	MovingMsg string
	MovedMsg  string
}

type MoveType string

type MoveFlags struct {
	DryRun     bool
	ArtDetails *config.ArtifactoryDetails
}

func (flags *MoveFlags) GetArtifactoryDetails() *config.ArtifactoryDetails {
	return flags.ArtDetails
}

func (flags *MoveFlags) IsDryRun() bool {
	return flags.DryRun
}<commit_msg>Specs support<commit_after>package utils

import (
	"strings"
	"fmt"
	"strconv"
	"github.com/jfrogdev/jfrog-cli-go/utils/cliutils"
	"github.com/jfrogdev/jfrog-cli-go/utils/ioutils"
	"github.com/jfrogdev/jfrog-cli-go/utils/config"
	"github.com/jfrogdev/jfrog-cli-go/utils/cliutils/logger"
)

const (
	MOVE MoveType = "move"
	COPY MoveType = "copy"
)

func MoveFilesWrapper(moveSpec *SpecFiles, flags *MoveFlags, moveType MoveType) (err error) {
	PreCommandSetup(flags)
	for i := 0; i < len(moveSpec.Files); i++ {
		switch moveSpec.Get(i).GetSpecType() {
		case WILDCARD:
			err = moveWildcard(moveSpec.Get(i), flags, moveType)
		case SIMPLE:
			err = moveSimple(moveSpec.Get(i), flags, moveType)
		case AQL:
			err = moveAql(moveSpec.Get(i), flags, moveType)
		}
		if err != nil {
			return
		}
	}
	return
}

func moveAql(fileSpec *Files, flags *MoveFlags, moveType MoveType) error {
	resultItems, err := AqlSearchBySpec(fileSpec.Aql, flags)
	if err != nil {
		return err
	}
	return moveFiles("", resultItems, fileSpec, flags, moveType)
}

func moveWildcard(fileSpec *Files, flags *MoveFlags, moveType MoveType) error {
	isRecursive, err := cliutils.StringToBool(fileSpec.Recursive, true)
	if err != nil {
		return err
	}
	resultItems, err := AqlSearchDefaultReturnFields(fileSpec.Pattern, isRecursive, fileSpec.Props, flags)
	if err != nil {
		return err
	}
	regexpPath := cliutils.PathToRegExp(fileSpec.Pattern)
	return moveFiles(regexpPath, resultItems, fileSpec, flags, moveType)
}

func moveSimple(fileSpec *Files, flags *MoveFlags, moveType MoveType) error {

	cleanPattern := cliutils.StripChars(fileSpec.Pattern, "()")
	patternFileName, _ := ioutils.GetFileAndDirFromPath(fileSpec.Pattern)

	regexpPattern := cliutils.PathToRegExp(fileSpec.Pattern)
	placeHolderTarget, err := cliutils.ReformatRegexp(regexpPattern, cleanPattern, fileSpec.Target)
	if err != nil {
		return err
	}

	if strings.HasSuffix(placeHolderTarget, "/") {
		placeHolderTarget += patternFileName
	}
	_, err = moveFile(cleanPattern, placeHolderTarget, flags, moveType)
	return err
}

func moveFiles(regexpPath string, resultItems []AqlSearchResultItem, fileSpec *Files, flags *MoveFlags, moveType MoveType) error {
	movedCount := 0

	for _, v := range resultItems {
		destPathLocal := fileSpec.Target
		isFlat, err := cliutils.StringToBool(fileSpec.Flat, true)
		if err != nil {
			return err
		}
		if !isFlat {
			if strings.Contains(destPathLocal, "/") {
				file, dir := ioutils.GetFileAndDirFromPath(destPathLocal)
				destPathLocal = cliutils.TrimPath(dir + "/" + v.Path + "/" + file)
			} else {
				destPathLocal = cliutils.TrimPath(destPathLocal + "/" + v.Path + "/")
			}
		}
		destFile, err := cliutils.ReformatRegexp(regexpPath, v.GetFullUrl(), destPathLocal)
		if err != nil {
			return err
		}
		if strings.HasSuffix(destFile, "/") {
			destFile += v.Name
		}
		success, err := moveFile(v.GetFullUrl(), destFile, flags, moveType)
		if err != nil {
			return err
		}
		movedCount += cliutils.Bool2Int(success)
	}

	logger.Logger.Info(moveMsgs[moveType].MovedMsg + " " + strconv.Itoa(movedCount) + " artifacts in Artifactory")
	return nil
}

func moveFile(sourcePath, destPath string, flags *MoveFlags, moveType MoveType) (bool, error) {
	message := moveMsgs[moveType].MovingMsg + " artifact: " + sourcePath + " to " + destPath
	if flags.DryRun == true {
		fmt.Println("[Dry run] " + message)
		return true, nil
	}

	logger.Logger.Info(message)

	moveUrl := flags.ArtDetails.Url
	restApi := "api/" + string(moveType) + "/" + sourcePath
	requestFullUrl, err := BuildArtifactoryUrl(moveUrl, restApi, map[string]string{"to": destPath})
	if err != nil {
		return false, err
	}
	httpClientsDetails := GetArtifactoryHttpClientDetails(flags.ArtDetails)
	resp, _, err := ioutils.SendPost(requestFullUrl, nil, httpClientsDetails)
	if err != nil {
		return false, err
	}

	logger.Logger.Info("Artifactory response:", resp.Status)
	return resp.StatusCode == 200, nil
}

var moveMsgs = map[MoveType]MoveOptions{
	MOVE: MoveOptions{MovingMsg: "Moving", MovedMsg: "Moved"},
	COPY: MoveOptions{MovingMsg: "Copying", MovedMsg: "Copied"},
}

type MoveOptions struct {
	MovingMsg string
	MovedMsg  string
}

type MoveType string

type MoveFlags struct {
	DryRun     bool
	ArtDetails *config.ArtifactoryDetails
}

func (flags *MoveFlags) GetArtifactoryDetails() *config.ArtifactoryDetails {
	return flags.ArtDetails
}

func (flags *MoveFlags) IsDryRun() bool {
	return flags.DryRun
}<|endoftext|>


<commit_before>package check_route_test

import (
	"fmt"
	"time"

	. "github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry-incubator/cf-test-helpers/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("CheckRoute", func() {
	const (
		assertionTimeout = 10.0
	)

	var (
		context  *helpers.ConfiguredContext
		hostName string

		env *helpers.Environment
	)

	config := helpers.LoadConfig()

	BeforeEach(func() {
		hostName = generator.RandomName()

		context = helpers.NewContext(config)
		env = helpers.NewEnvironment(context)

		env.Setup()
	})

	AfterEach(func() {
		Cf("delete-route", config.AppsDomain, "-n", hostName)

		env.Teardown()
	})

	It("can check if a route exists", func() {
		AsUser(context.AdminUserContext(), 60*time.Second, func() {
			space := context.RegularUserContext().Space

			target := Cf("target", "-o", context.RegularUserContext().Org, "-s", space).Wait(assertionTimeout)
			Expect(target.ExitCode()).To(Equal(0))

			createRoute := Cf("create-route", space, config.AppsDomain, "-n", hostName).Wait(assertionTimeout)
			Expect(createRoute.ExitCode()).To(Equal(0))

			checkRoute := Cf("check-route", hostName, config.AppsDomain).Wait(assertionTimeout)
			Expect(checkRoute.Out.Contents()).To(ContainSubstring(fmt.Sprintf("Route %s.%s does exist", hostName, config.AppsDomain)))

			deleteRoute := Cf("delete-route", config.AppsDomain, "-n", hostName, "-f").Wait(assertionTimeout + 30)
			Expect(deleteRoute.ExitCode()).To(Equal(0))

			checkRoute = Cf("check-route", hostName, config.AppsDomain).Wait(assertionTimeout)
			Expect(checkRoute.Out.Contents()).To(ContainSubstring(fmt.Sprintf("Route %s.%s does not exist", hostName, config.AppsDomain)))
		})
	})
})
<commit_msg>Increase timeout for all check_route test<commit_after>package check_route_test

import (
	"fmt"
	"time"

	. "github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry-incubator/cf-test-helpers/helpers"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("CheckRoute", func() {
	const (
		assertionTimeout = 30.0
	)

	var (
		context  *helpers.ConfiguredContext
		hostName string

		env *helpers.Environment
	)

	config := helpers.LoadConfig()

	BeforeEach(func() {
		hostName = generator.RandomName()

		context = helpers.NewContext(config)
		env = helpers.NewEnvironment(context)

		env.Setup()
	})

	AfterEach(func() {
		Cf("delete-route", config.AppsDomain, "-n", hostName)

		env.Teardown()
	})

	It("can check if a route exists", func() {
		AsUser(context.AdminUserContext(), 60*time.Second, func() {
			space := context.RegularUserContext().Space

			target := Cf("target", "-o", context.RegularUserContext().Org, "-s", space).Wait(assertionTimeout)
			Expect(target.ExitCode()).To(Equal(0))

			createRoute := Cf("create-route", space, config.AppsDomain, "-n", hostName).Wait(assertionTimeout)
			Expect(createRoute.ExitCode()).To(Equal(0))

			checkRoute := Cf("check-route", hostName, config.AppsDomain).Wait(assertionTimeout)
			Expect(checkRoute.Out.Contents()).To(ContainSubstring(fmt.Sprintf("Route %s.%s does exist", hostName, config.AppsDomain)))

			deleteRoute := Cf("delete-route", config.AppsDomain, "-n", hostName, "-f").Wait(assertionTimeout)
			Expect(deleteRoute.ExitCode()).To(Equal(0))

			checkRoute = Cf("check-route", hostName, config.AppsDomain).Wait(assertionTimeout)
			Expect(checkRoute.Out.Contents()).To(ContainSubstring(fmt.Sprintf("Route %s.%s does not exist", hostName, config.AppsDomain)))
		})
	})
})
<|endoftext|>


<commit_before>package twitch

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"
)

const (
	CHANNELS_BASE_URL = "https://api.twitch.tv/kraken/channels/"
	STREAMS_BASE_URL  = "https://api.twitch.tv/kraken/streams/"
)

type StreamsData struct {
	Links struct {
		Channel string `json:"channel"`
		Self    string `json:"self"`
	} `json:"_links"`
	Stream struct {
		ID    float64 `json:"_id"`
		Links struct {
			Self string `json:"self"`
		} `json:"_links"`
		AverageFps float64 `json:"average_fps"`
		Channel    struct {
			ID    float64 `json:"_id"`
			Links struct {
				Chat          string `json:"chat"`
				Commercial    string `json:"commercial"`
				Editors       string `json:"editors"`
				Features      string `json:"features"`
				Follows       string `json:"follows"`
				Self          string `json:"self"`
				StreamKey     string `json:"stream_key"`
				Subscriptions string `json:"subscriptions"`
				Teams         string `json:"teams"`
				Videos        string `json:"videos"`
			} `json:"_links"`
			Background                   interface{} `json:"background"`
			Banner                       string      `json:"banner"`
			BroadcasterLanguage          string      `json:"broadcaster_language"`
			CreatedAt                    string      `json:"created_at"`
			Delay                        float64     `json:"delay"`
			DisplayName                  string      `json:"display_name"`
			Followers                    float64     `json:"followers"`
			Game                         string      `json:"game"`
			Language                     string      `json:"language"`
			Logo                         string      `json:"logo"`
			Mature                       bool        `json:"mature"`
			Name                         string      `json:"name"`
			Partner                      bool        `json:"partner"`
			ProfileBanner                string      `json:"profile_banner"`
			ProfileBannerBackgroundColor string      `json:"profile_banner_background_color"`
			Status                       string      `json:"status"`
			UpdatedAt                    string      `json:"updated_at"`
			URL                          string      `json:"url"`
			VideoBanner                  string      `json:"video_banner"`
			Views                        float64     `json:"views"`
		} `json:"channel"`
		CreatedAt string `json:"created_at"`
		Game      string `json:"game"`
		Preview   struct {
			Large    string `json:"large"`
			Medium   string `json:"medium"`
			Small    string `json:"small"`
			Template string `json:"template"`
		} `json:"preview"`
		VideoHeight float64 `json:"video_height"`
		Viewers     float64 `json:"viewers"`
	} `json:"stream"`
}

type TwitchApi struct {
	Channel      string
	ChannelOauth string
	ChannelsUrl  string
	StreamsURL   string
}

func New(ChannelName, Oauth string) *TwitchApi {
	return &TwitchApi{
		Channel:      ChannelName,
		ChannelOauth: Oauth,
		ChannelsUrl:  CHANNELS_BASE_URL + ChannelName,
		StreamsURL:   STREAMS_BASE_URL + ChannelName,
	}
}

func (tw *TwitchApi) UpdateStatus(status string) error {
	client := &http.Client{}
	urlp, err := url.Parse(tw.ChannelsUrl)
	if err != nil {
		return err
	}

	param := url.Values{}
	param.Add("channel[status]", status)
	param.Add("_method", "put")
	param.Add("oauth_token", tw.ChannelOauth)
	urlp.RawQuery = param.Encode()

	_, err = client.Get(urlp.String())
	if err != nil {
		return err
	}

	return nil
}

func (tw *TwitchApi) UpdateGame(game string) error {
	client := &http.Client{}
	urlp, err := url.Parse(tw.ChannelsUrl)
	if err != nil {
		return err
	}

	param := url.Values{}
	param.Add("channel[game]", game)
	param.Add("_method", "put")
	param.Add("oauth_token", tw.ChannelOauth)
	urlp.RawQuery = param.Encode()

	_, err = client.Get(urlp.String())
	if err != nil {
		return err
	}

	return nil
}

func (tw *TwitchApi) Uptime() (string, error) {
	var stream *StreamsData
	res, err := http.Get(tw.StreamsURL)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", err
	}
	if err := json.Unmarshal(body, &stream); err != nil {
		return "", err
	}

	layout := "2006-01-02T15:04:05Z"
	startTime := stream.Stream.CreatedAt
	if startTime != "" {
		parsedTime, err := time.Parse(layout, startTime)
		if err != nil {
			return "", err
		}
		duration := time.Since(parsedTime)
		return duration.String(), nil
	} else {
		return "", nil
	}
}
<commit_msg>unexport streamsdata<commit_after>package twitch

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"
)

const (
	CHANNELS_BASE_URL = "https://api.twitch.tv/kraken/channels/"
	STREAMS_BASE_URL  = "https://api.twitch.tv/kraken/streams/"
)

type streamsData struct {
	Links struct {
		Channel string `json:"channel"`
		Self    string `json:"self"`
	} `json:"_links"`
	Stream struct {
		ID    float64 `json:"_id"`
		Links struct {
			Self string `json:"self"`
		} `json:"_links"`
		AverageFps float64 `json:"average_fps"`
		Channel    struct {
			ID    float64 `json:"_id"`
			Links struct {
				Chat          string `json:"chat"`
				Commercial    string `json:"commercial"`
				Editors       string `json:"editors"`
				Features      string `json:"features"`
				Follows       string `json:"follows"`
				Self          string `json:"self"`
				StreamKey     string `json:"stream_key"`
				Subscriptions string `json:"subscriptions"`
				Teams         string `json:"teams"`
				Videos        string `json:"videos"`
			} `json:"_links"`
			Background                   interface{} `json:"background"`
			Banner                       string      `json:"banner"`
			BroadcasterLanguage          string      `json:"broadcaster_language"`
			CreatedAt                    string      `json:"created_at"`
			Delay                        float64     `json:"delay"`
			DisplayName                  string      `json:"display_name"`
			Followers                    float64     `json:"followers"`
			Game                         string      `json:"game"`
			Language                     string      `json:"language"`
			Logo                         string      `json:"logo"`
			Mature                       bool        `json:"mature"`
			Name                         string      `json:"name"`
			Partner                      bool        `json:"partner"`
			ProfileBanner                string      `json:"profile_banner"`
			ProfileBannerBackgroundColor string      `json:"profile_banner_background_color"`
			Status                       string      `json:"status"`
			UpdatedAt                    string      `json:"updated_at"`
			URL                          string      `json:"url"`
			VideoBanner                  string      `json:"video_banner"`
			Views                        float64     `json:"views"`
		} `json:"channel"`
		CreatedAt string `json:"created_at"`
		Game      string `json:"game"`
		Preview   struct {
			Large    string `json:"large"`
			Medium   string `json:"medium"`
			Small    string `json:"small"`
			Template string `json:"template"`
		} `json:"preview"`
		VideoHeight float64 `json:"video_height"`
		Viewers     float64 `json:"viewers"`
	} `json:"stream"`
}

type TwitchApi struct {
	Channel      string
	ChannelOauth string
	ChannelsUrl  string
	StreamsURL   string
}

func New(ChannelName, Oauth string) *TwitchApi {
	return &TwitchApi{
		Channel:      ChannelName,
		ChannelOauth: Oauth,
		ChannelsUrl:  CHANNELS_BASE_URL + ChannelName,
		StreamsURL:   STREAMS_BASE_URL + ChannelName,
	}
}

func (tw *TwitchApi) UpdateStatus(status string) error {
	client := &http.Client{}
	urlp, err := url.Parse(tw.ChannelsUrl)
	if err != nil {
		return err
	}

	param := url.Values{}
	param.Add("channel[status]", status)
	param.Add("_method", "put")
	param.Add("oauth_token", tw.ChannelOauth)
	urlp.RawQuery = param.Encode()

	_, err = client.Get(urlp.String())
	if err != nil {
		return err
	}

	return nil
}

func (tw *TwitchApi) UpdateGame(game string) error {
	client := &http.Client{}
	urlp, err := url.Parse(tw.ChannelsUrl)
	if err != nil {
		return err
	}

	param := url.Values{}
	param.Add("channel[game]", game)
	param.Add("_method", "put")
	param.Add("oauth_token", tw.ChannelOauth)
	urlp.RawQuery = param.Encode()

	_, err = client.Get(urlp.String())
	if err != nil {
		return err
	}

	return nil
}

func (tw *TwitchApi) Uptime() (string, error) {
	var stream *streamsData
	res, err := http.Get(tw.StreamsURL)
	if err != nil {
		return "", err
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return "", err
	}
	if err := json.Unmarshal(body, &stream); err != nil {
		return "", err
	}

	layout := "2006-01-02T15:04:05Z"
	startTime := stream.Stream.CreatedAt
	if startTime != "" {
		parsedTime, err := time.Parse(layout, startTime)
		if err != nil {
			return "", err
		}
		duration := time.Since(parsedTime)
		return duration.String(), nil
	} else {
		return "", nil
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/accessanalyzer"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

const (
	// Maximum amount of time to wait for Organizations eventual consistency on creation
	// This timeout value is much higher than usual since the cross-service validation
	// appears to be consistently caching for 5 minutes:
	// --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer/Type_Organization (315.86s)
	accessAnalyzerOrganizationCreationTimeout = 10 * time.Minute
)

func resourceAwsAccessAnalyzerAnalyzer() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsAccessAnalyzerAnalyzerCreate,
		Read:   resourceAwsAccessAnalyzerAnalyzerRead,
		Update: resourceAwsAccessAnalyzerAnalyzerUpdate,
		Delete: resourceAwsAccessAnalyzerAnalyzerDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"analyzer_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
				ValidateFunc: validation.All(
					validation.StringLenBetween(1, 255),
					validation.StringMatch(regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_.-]*$`), ""),
				),
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"tags": tagsSchema(),
			"type": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  accessanalyzer.TypeAccount,
				ValidateFunc: validation.StringInSlice([]string{
					accessanalyzer.TypeAccount,
					accessanalyzer.TypeOrganization,
				}, false),
			},
		},
	}
}

func resourceAwsAccessAnalyzerAnalyzerCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn
	analyzerName := d.Get("analyzer_name").(string)

	input := &accessanalyzer.CreateAnalyzerInput{
		AnalyzerName: aws.String(analyzerName),
		ClientToken:  aws.String(resource.UniqueId()),
		Tags:         keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().AccessanalyzerTags(),
		Type:         aws.String(d.Get("type").(string)),
	}

	// Handle Organizations eventual consistency
	err := resource.Retry(accessAnalyzerOrganizationCreationTimeout, func() *resource.RetryError {
		_, err := conn.CreateAnalyzer(input)

		if isAWSErr(err, accessanalyzer.ErrCodeValidationException, "You must create an organization") {
			return resource.RetryableError(err)
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return nil
	})

	if isResourceTimeoutError(err) {
		_, err = conn.CreateAnalyzer(input)
	}

	if err != nil {
		return fmt.Errorf("error creating Access Analyzer Analyzer (%s): %s", analyzerName, err)
	}

	d.SetId(analyzerName)

	return resourceAwsAccessAnalyzerAnalyzerRead(d, meta)
}

func resourceAwsAccessAnalyzerAnalyzerRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	input := &accessanalyzer.GetAnalyzerInput{
		AnalyzerName: aws.String(d.Id()),
	}

	output, err := conn.GetAnalyzer(input)

	if isAWSErr(err, accessanalyzer.ErrCodeResourceNotFoundException, "") {
		log.Printf("[WARN] Access Analyzer Analyzer (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("error getting Access Analyzer Analyzer (%s): %s", d.Id(), err)
	}

	if output == nil || output.Analyzer == nil {
		return fmt.Errorf("error getting Access Analyzer Analyzer (%s): empty response", d.Id())
	}

	d.Set("analyzer_name", output.Analyzer.Name)
	d.Set("arn", output.Analyzer.Arn)

	if err := d.Set("tags", keyvaluetags.AccessanalyzerKeyValueTags(output.Analyzer.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	d.Set("type", output.Analyzer.Type)

	return nil
}

func resourceAwsAccessAnalyzerAnalyzerUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn

	if d.HasChange("tags") {
		o, n := d.GetChange("tags")
		if err := keyvaluetags.AccessanalyzerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
			return fmt.Errorf("error updating Access Analyzer Analyzer (%s) tags: %s", d.Id(), err)
		}
	}

	return resourceAwsAccessAnalyzerAnalyzerRead(d, meta)
}

func resourceAwsAccessAnalyzerAnalyzerDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn

	input := &accessanalyzer.DeleteAnalyzerInput{
		AnalyzerName: aws.String(d.Id()),
		ClientToken:  aws.String(resource.UniqueId()),
	}

	_, err := conn.DeleteAnalyzer(input)

	if isAWSErr(err, accessanalyzer.ErrCodeResourceNotFoundException, "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("error deleting Access Analyzer Analyzer (%s): %s", d.Id(), err)
	}

	return nil
}
<commit_msg>Improves validation message<commit_after>package aws

import (
	"fmt"
	"log"
	"regexp"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/accessanalyzer"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
)

const (
	// Maximum amount of time to wait for Organizations eventual consistency on creation
	// This timeout value is much higher than usual since the cross-service validation
	// appears to be consistently caching for 5 minutes:
	// --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer/Type_Organization (315.86s)
	accessAnalyzerOrganizationCreationTimeout = 10 * time.Minute
)

func resourceAwsAccessAnalyzerAnalyzer() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsAccessAnalyzerAnalyzerCreate,
		Read:   resourceAwsAccessAnalyzerAnalyzerRead,
		Update: resourceAwsAccessAnalyzerAnalyzerUpdate,
		Delete: resourceAwsAccessAnalyzerAnalyzerDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"analyzer_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
				ValidateFunc: validation.All(
					validation.StringLenBetween(1, 255),
					validation.StringMatch(regexp.MustCompile(`^[A-Za-z][A-Za-z0-9_.-]*$`), "must begin with a letter and contain only alphanumeric, underscore, period, or hyphen characters"),
				),
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"tags": tagsSchema(),
			"type": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Default:  accessanalyzer.TypeAccount,
				ValidateFunc: validation.StringInSlice([]string{
					accessanalyzer.TypeAccount,
					accessanalyzer.TypeOrganization,
				}, false),
			},
		},
	}
}

func resourceAwsAccessAnalyzerAnalyzerCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn
	analyzerName := d.Get("analyzer_name").(string)

	input := &accessanalyzer.CreateAnalyzerInput{
		AnalyzerName: aws.String(analyzerName),
		ClientToken:  aws.String(resource.UniqueId()),
		Tags:         keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().AccessanalyzerTags(),
		Type:         aws.String(d.Get("type").(string)),
	}

	// Handle Organizations eventual consistency
	err := resource.Retry(accessAnalyzerOrganizationCreationTimeout, func() *resource.RetryError {
		_, err := conn.CreateAnalyzer(input)

		if isAWSErr(err, accessanalyzer.ErrCodeValidationException, "You must create an organization") {
			return resource.RetryableError(err)
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return nil
	})

	if isResourceTimeoutError(err) {
		_, err = conn.CreateAnalyzer(input)
	}

	if err != nil {
		return fmt.Errorf("error creating Access Analyzer Analyzer (%s): %s", analyzerName, err)
	}

	d.SetId(analyzerName)

	return resourceAwsAccessAnalyzerAnalyzerRead(d, meta)
}

func resourceAwsAccessAnalyzerAnalyzerRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn
	ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig

	input := &accessanalyzer.GetAnalyzerInput{
		AnalyzerName: aws.String(d.Id()),
	}

	output, err := conn.GetAnalyzer(input)

	if isAWSErr(err, accessanalyzer.ErrCodeResourceNotFoundException, "") {
		log.Printf("[WARN] Access Analyzer Analyzer (%s) not found, removing from state", d.Id())
		d.SetId("")
		return nil
	}

	if err != nil {
		return fmt.Errorf("error getting Access Analyzer Analyzer (%s): %s", d.Id(), err)
	}

	if output == nil || output.Analyzer == nil {
		return fmt.Errorf("error getting Access Analyzer Analyzer (%s): empty response", d.Id())
	}

	d.Set("analyzer_name", output.Analyzer.Name)
	d.Set("arn", output.Analyzer.Arn)

	if err := d.Set("tags", keyvaluetags.AccessanalyzerKeyValueTags(output.Analyzer.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
		return fmt.Errorf("error setting tags: %s", err)
	}

	d.Set("type", output.Analyzer.Type)

	return nil
}

func resourceAwsAccessAnalyzerAnalyzerUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn

	if d.HasChange("tags") {
		o, n := d.GetChange("tags")
		if err := keyvaluetags.AccessanalyzerUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
			return fmt.Errorf("error updating Access Analyzer Analyzer (%s) tags: %s", d.Id(), err)
		}
	}

	return resourceAwsAccessAnalyzerAnalyzerRead(d, meta)
}

func resourceAwsAccessAnalyzerAnalyzerDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).accessanalyzerconn

	input := &accessanalyzer.DeleteAnalyzerInput{
		AnalyzerName: aws.String(d.Id()),
		ClientToken:  aws.String(resource.UniqueId()),
	}

	_, err := conn.DeleteAnalyzer(input)

	if isAWSErr(err, accessanalyzer.ErrCodeResourceNotFoundException, "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("error deleting Access Analyzer Analyzer (%s): %s", d.Id(), err)
	}

	return nil
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/arn"
	"github.com/aws/aws-sdk-go/service/codeartifact"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceAwsCodeArtifactRepository() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCodeArtifactRepositoryCreate,
		Read:   resourceAwsCodeArtifactRepositoryRead,
		Update: resourceAwsCodeArtifactRepositoryUpdate,
		Delete: resourceAwsCodeArtifactRepositoryDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"repository": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"domain": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"domain_owner": {
				Type:     schema.TypeString,
				Optional: true,
				ForceNew: true,
				Computed: true,
			},
			"description": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"upstream": {
				Type:     schema.TypeList,
				MinItems: 1,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"repository_name": {
							Type:     schema.TypeString,
							Required: true,
						},
					},
				},
			},
			"external_connections": {
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"external_connection_name": {
							Type:     schema.TypeString,
							Optional: true,
						},
						"package_format": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"status": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"administrator_account": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsCodeArtifactRepositoryCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn
	log.Print("[DEBUG] Creating CodeArtifact Repository")

	params := &codeartifact.CreateRepositoryInput{
		Repository: aws.String(d.Get("repository").(string)),
		Domain:     aws.String(d.Get("domain").(string)),
	}

	if v, ok := d.GetOk("description"); ok {
		params.Description = aws.String(v.(string))
	}

	if v, ok := d.GetOk("domain_owner"); ok {
		params.DomainOwner = aws.String(v.(string))
	}

	if v, ok := d.GetOk("upstream"); ok {
		params.Upstreams = expandCodeArtifactUpstreams(v.([]interface{}))
	}

	res, err := conn.CreateRepository(params)
	if err != nil {
		return fmt.Errorf("error creating CodeArtifact Repository: %w", err)
	}

	repo := res.Repository
	d.SetId(aws.StringValue(repo.Arn))

	if v, ok := d.GetOk("external_connections"); ok {
		externalConnection := v.([]interface{})[0].(map[string]interface{})
		input := &codeartifact.AssociateExternalConnectionInput{
			Domain:             repo.DomainName,
			Repository:         repo.Name,
			DomainOwner:        repo.DomainOwner,
			ExternalConnection: aws.String(externalConnection["external_connection_name"].(string)),
		}

		_, err := conn.AssociateExternalConnection(input)
		if err != nil {
			return fmt.Errorf("error associating external connection to CodeArtifact repository: %w", err)
		}
	}

	return resourceAwsCodeArtifactRepositoryRead(d, meta)
}

func resourceAwsCodeArtifactRepositoryUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn
	log.Print("[DEBUG] Updating CodeArtifact Repository")

	params := &codeartifact.UpdateRepositoryInput{
		Repository:  aws.String(d.Get("repository").(string)),
		Domain:      aws.String(d.Get("domain").(string)),
		DomainOwner: aws.String(d.Get("domain_owner").(string)),
	}

	if d.HasChange("description") {
		if v, ok := d.GetOk("description"); ok {
			params.Description = aws.String(v.(string))
		}
	}

	if d.HasChange("upstream") {
		if v, ok := d.GetOk("upstream"); ok {
			params.Upstreams = expandCodeArtifactUpstreams(v.([]interface{}))
		}
	}

	_, err := conn.UpdateRepository(params)
	if err != nil {
		return fmt.Errorf("error updating CodeArtifact Repository: %w", err)
	}

	if d.HasChange("external_connections") {
		if v, ok := d.GetOk("external_connections"); ok {
			externalConnection := v.([]interface{})[0].(map[string]interface{})
			input := &codeartifact.AssociateExternalConnectionInput{
				Repository:         aws.String(d.Get("repository").(string)),
				Domain:             aws.String(d.Get("domain").(string)),
				DomainOwner:        aws.String(d.Get("domain_owner").(string)),
				ExternalConnection: aws.String(externalConnection["external_connection_name"].(string)),
			}

			_, err := conn.AssociateExternalConnection(input)
			if err != nil {
				return fmt.Errorf("error associating external connection to CodeArtifact repository: %w", err)
			}
		} else {
			oldConn, _ := d.GetChange("external_connections")
			externalConnection := oldConn.([]interface{})[0].(map[string]interface{})
			input := &codeartifact.DisassociateExternalConnectionInput{
				Repository:         aws.String(d.Get("repository").(string)),
				Domain:             aws.String(d.Get("domain").(string)),
				DomainOwner:        aws.String(d.Get("domain_owner").(string)),
				ExternalConnection: aws.String(externalConnection["external_connection_name"].(string)),
			}

			_, err := conn.DisassociateExternalConnection(input)
			if err != nil {
				return fmt.Errorf("error disassociating external connection to CodeArtifact repository: %w", err)
			}
		}
	}

	return resourceAwsCodeArtifactRepositoryRead(d, meta)
}

func resourceAwsCodeArtifactRepositoryRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn

	log.Printf("[DEBUG] Reading CodeArtifact Repository: %s", d.Id())

	owner, domain, repo, err := decodeCodeArtifactRepositoryID(d.Id())
	if err != nil {
		return err
	}
	sm, err := conn.DescribeRepository(&codeartifact.DescribeRepositoryInput{
		Repository:  aws.String(repo),
		Domain:      aws.String(domain),
		DomainOwner: aws.String(owner),
	})
	if err != nil {
		if isAWSErr(err, codeartifact.ErrCodeResourceNotFoundException, "") {
			log.Printf("[WARN] CodeArtifact Repository %q not found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return fmt.Errorf("error reading CodeArtifact Repository (%s): %w", d.Id(), err)
	}

	d.Set("repository", sm.Repository.Name)
	d.Set("arn", sm.Repository.Arn)
	d.Set("domain_owner", sm.Repository.DomainOwner)
	d.Set("domain", sm.Repository.DomainName)
	d.Set("administrator_account", sm.Repository.AdministratorAccount)
	d.Set("description", sm.Repository.Description)

	if sm.Repository.Upstreams != nil {
		if err := d.Set("upstream", flattenCodeArtifactUpstreams(sm.Repository.Upstreams)); err != nil {
			return fmt.Errorf("[WARN] Error setting upstream: %w", err)
		}
	}

	if sm.Repository.ExternalConnections != nil {
		if err := d.Set("external_connections", flattenCodeArtifactExternalConnections(sm.Repository.ExternalConnections)); err != nil {
			return fmt.Errorf("[WARN] Error setting external_connections: %w", err)
		}
	}

	return nil
}

func resourceAwsCodeArtifactRepositoryDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn
	log.Printf("[DEBUG] Deleting CodeArtifact Repository: %s", d.Id())

	owner, domain, repo, err := decodeCodeArtifactRepositoryID(d.Id())
	if err != nil {
		return err
	}
	input := &codeartifact.DeleteRepositoryInput{
		Repository:  aws.String(repo),
		Domain:      aws.String(domain),
		DomainOwner: aws.String(owner),
	}

	_, err = conn.DeleteRepository(input)

	if isAWSErr(err, codeartifact.ErrCodeResourceNotFoundException, "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("error deleting CodeArtifact Repository (%s): %w", d.Id(), err)
	}

	return nil
}

func expandCodeArtifactUpstreams(l []interface{}) []*codeartifact.UpstreamRepository {
	upstreams := []*codeartifact.UpstreamRepository{}

	for _, mRaw := range l {
		m := mRaw.(map[string]interface{})
		upstream := &codeartifact.UpstreamRepository{
			RepositoryName: aws.String(m["repository_name"].(string)),
		}

		upstreams = append(upstreams, upstream)
	}

	return upstreams
}

func flattenCodeArtifactUpstreams(upstreams []*codeartifact.UpstreamRepositoryInfo) []interface{} {
	if len(upstreams) == 0 {
		return nil
	}

	var ls []interface{}

	for _, upstream := range upstreams {
		m := map[string]interface{}{
			"repository_name": aws.StringValue(upstream.RepositoryName),
		}

		ls = append(ls, m)
	}

	return ls
}

func flattenCodeArtifactExternalConnections(connections []*codeartifact.RepositoryExternalConnectionInfo) []interface{} {
	if len(connections) == 0 {
		return nil
	}

	var ls []interface{}

	for _, connection := range connections {
		m := map[string]interface{}{
			"external_connection_name": aws.StringValue(connection.ExternalConnectionName),
			"package_format":           aws.StringValue(connection.PackageFormat),
			"status":                   aws.StringValue(connection.Status),
		}

		ls = append(ls, m)
	}

	return ls
}

func decodeCodeArtifactRepositoryID(id string) (string, string, string, error) {
	repoArn, err := arn.Parse(id)
	if err != nil {
		return "", "", "", err
	}

	idParts := strings.Split(strings.TrimPrefix(repoArn.Resource, "repository/"), "/")
	if len(idParts) != 2 {
		return "", "", "", fmt.Errorf("expected resource part of arn in format DomainName/RepositoryName, received: %s", repoArn.Resource)
	}
	return repoArn.AccountID, idParts[0], idParts[1], nil
}
<commit_msg>conn name is require and add validation to domain owner<commit_after>package aws

import (
	"fmt"
	"log"
	"strings"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/arn"
	"github.com/aws/aws-sdk-go/service/codeartifact"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceAwsCodeArtifactRepository() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsCodeArtifactRepositoryCreate,
		Read:   resourceAwsCodeArtifactRepositoryRead,
		Update: resourceAwsCodeArtifactRepositoryUpdate,
		Delete: resourceAwsCodeArtifactRepositoryDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"repository": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"domain": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"domain_owner": {
				Type:         schema.TypeString,
				Optional:     true,
				ForceNew:     true,
				Computed:     true,
				ValidateFunc: validateAwsAccountId,
			},
			"description": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"upstream": {
				Type:     schema.TypeList,
				MinItems: 1,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"repository_name": {
							Type:     schema.TypeString,
							Required: true,
						},
					},
				},
			},
			"external_connections": {
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"external_connection_name": {
							Type:     schema.TypeString,
							Required: true,
						},
						"package_format": {
							Type:     schema.TypeString,
							Computed: true,
						},
						"status": {
							Type:     schema.TypeString,
							Computed: true,
						},
					},
				},
			},
			"administrator_account": {
				Type:     schema.TypeString,
				Computed: true,
			},
		},
	}
}

func resourceAwsCodeArtifactRepositoryCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn
	log.Print("[DEBUG] Creating CodeArtifact Repository")

	params := &codeartifact.CreateRepositoryInput{
		Repository: aws.String(d.Get("repository").(string)),
		Domain:     aws.String(d.Get("domain").(string)),
	}

	if v, ok := d.GetOk("description"); ok {
		params.Description = aws.String(v.(string))
	}

	if v, ok := d.GetOk("domain_owner"); ok {
		params.DomainOwner = aws.String(v.(string))
	}

	if v, ok := d.GetOk("upstream"); ok {
		params.Upstreams = expandCodeArtifactUpstreams(v.([]interface{}))
	}

	res, err := conn.CreateRepository(params)
	if err != nil {
		return fmt.Errorf("error creating CodeArtifact Repository: %w", err)
	}

	repo := res.Repository
	d.SetId(aws.StringValue(repo.Arn))

	if v, ok := d.GetOk("external_connections"); ok {
		externalConnection := v.([]interface{})[0].(map[string]interface{})
		input := &codeartifact.AssociateExternalConnectionInput{
			Domain:             repo.DomainName,
			Repository:         repo.Name,
			DomainOwner:        repo.DomainOwner,
			ExternalConnection: aws.String(externalConnection["external_connection_name"].(string)),
		}

		_, err := conn.AssociateExternalConnection(input)
		if err != nil {
			return fmt.Errorf("error associating external connection to CodeArtifact repository: %w", err)
		}
	}

	return resourceAwsCodeArtifactRepositoryRead(d, meta)
}

func resourceAwsCodeArtifactRepositoryUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn
	log.Print("[DEBUG] Updating CodeArtifact Repository")

	params := &codeartifact.UpdateRepositoryInput{
		Repository:  aws.String(d.Get("repository").(string)),
		Domain:      aws.String(d.Get("domain").(string)),
		DomainOwner: aws.String(d.Get("domain_owner").(string)),
	}

	if d.HasChange("description") {
		if v, ok := d.GetOk("description"); ok {
			params.Description = aws.String(v.(string))
		}
	}

	if d.HasChange("upstream") {
		if v, ok := d.GetOk("upstream"); ok {
			params.Upstreams = expandCodeArtifactUpstreams(v.([]interface{}))
		}
	}

	_, err := conn.UpdateRepository(params)
	if err != nil {
		return fmt.Errorf("error updating CodeArtifact Repository: %w", err)
	}

	if d.HasChange("external_connections") {
		if v, ok := d.GetOk("external_connections"); ok {
			externalConnection := v.([]interface{})[0].(map[string]interface{})
			input := &codeartifact.AssociateExternalConnectionInput{
				Repository:         aws.String(d.Get("repository").(string)),
				Domain:             aws.String(d.Get("domain").(string)),
				DomainOwner:        aws.String(d.Get("domain_owner").(string)),
				ExternalConnection: aws.String(externalConnection["external_connection_name"].(string)),
			}

			_, err := conn.AssociateExternalConnection(input)
			if err != nil {
				return fmt.Errorf("error associating external connection to CodeArtifact repository: %w", err)
			}
		} else {
			oldConn, _ := d.GetChange("external_connections")
			externalConnection := oldConn.([]interface{})[0].(map[string]interface{})
			input := &codeartifact.DisassociateExternalConnectionInput{
				Repository:         aws.String(d.Get("repository").(string)),
				Domain:             aws.String(d.Get("domain").(string)),
				DomainOwner:        aws.String(d.Get("domain_owner").(string)),
				ExternalConnection: aws.String(externalConnection["external_connection_name"].(string)),
			}

			_, err := conn.DisassociateExternalConnection(input)
			if err != nil {
				return fmt.Errorf("error disassociating external connection to CodeArtifact repository: %w", err)
			}
		}
	}

	return resourceAwsCodeArtifactRepositoryRead(d, meta)
}

func resourceAwsCodeArtifactRepositoryRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn

	log.Printf("[DEBUG] Reading CodeArtifact Repository: %s", d.Id())

	owner, domain, repo, err := decodeCodeArtifactRepositoryID(d.Id())
	if err != nil {
		return err
	}
	sm, err := conn.DescribeRepository(&codeartifact.DescribeRepositoryInput{
		Repository:  aws.String(repo),
		Domain:      aws.String(domain),
		DomainOwner: aws.String(owner),
	})
	if err != nil {
		if isAWSErr(err, codeartifact.ErrCodeResourceNotFoundException, "") {
			log.Printf("[WARN] CodeArtifact Repository %q not found, removing from state", d.Id())
			d.SetId("")
			return nil
		}
		return fmt.Errorf("error reading CodeArtifact Repository (%s): %w", d.Id(), err)
	}

	d.Set("repository", sm.Repository.Name)
	d.Set("arn", sm.Repository.Arn)
	d.Set("domain_owner", sm.Repository.DomainOwner)
	d.Set("domain", sm.Repository.DomainName)
	d.Set("administrator_account", sm.Repository.AdministratorAccount)
	d.Set("description", sm.Repository.Description)

	if sm.Repository.Upstreams != nil {
		if err := d.Set("upstream", flattenCodeArtifactUpstreams(sm.Repository.Upstreams)); err != nil {
			return fmt.Errorf("[WARN] Error setting upstream: %w", err)
		}
	}

	if sm.Repository.ExternalConnections != nil {
		if err := d.Set("external_connections", flattenCodeArtifactExternalConnections(sm.Repository.ExternalConnections)); err != nil {
			return fmt.Errorf("[WARN] Error setting external_connections: %w", err)
		}
	}

	return nil
}

func resourceAwsCodeArtifactRepositoryDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).codeartifactconn
	log.Printf("[DEBUG] Deleting CodeArtifact Repository: %s", d.Id())

	owner, domain, repo, err := decodeCodeArtifactRepositoryID(d.Id())
	if err != nil {
		return err
	}
	input := &codeartifact.DeleteRepositoryInput{
		Repository:  aws.String(repo),
		Domain:      aws.String(domain),
		DomainOwner: aws.String(owner),
	}

	_, err = conn.DeleteRepository(input)

	if isAWSErr(err, codeartifact.ErrCodeResourceNotFoundException, "") {
		return nil
	}

	if err != nil {
		return fmt.Errorf("error deleting CodeArtifact Repository (%s): %w", d.Id(), err)
	}

	return nil
}

func expandCodeArtifactUpstreams(l []interface{}) []*codeartifact.UpstreamRepository {
	upstreams := []*codeartifact.UpstreamRepository{}

	for _, mRaw := range l {
		m := mRaw.(map[string]interface{})
		upstream := &codeartifact.UpstreamRepository{
			RepositoryName: aws.String(m["repository_name"].(string)),
		}

		upstreams = append(upstreams, upstream)
	}

	return upstreams
}

func flattenCodeArtifactUpstreams(upstreams []*codeartifact.UpstreamRepositoryInfo) []interface{} {
	if len(upstreams) == 0 {
		return nil
	}

	var ls []interface{}

	for _, upstream := range upstreams {
		m := map[string]interface{}{
			"repository_name": aws.StringValue(upstream.RepositoryName),
		}

		ls = append(ls, m)
	}

	return ls
}

func flattenCodeArtifactExternalConnections(connections []*codeartifact.RepositoryExternalConnectionInfo) []interface{} {
	if len(connections) == 0 {
		return nil
	}

	var ls []interface{}

	for _, connection := range connections {
		m := map[string]interface{}{
			"external_connection_name": aws.StringValue(connection.ExternalConnectionName),
			"package_format":           aws.StringValue(connection.PackageFormat),
			"status":                   aws.StringValue(connection.Status),
		}

		ls = append(ls, m)
	}

	return ls
}

func decodeCodeArtifactRepositoryID(id string) (string, string, string, error) {
	repoArn, err := arn.Parse(id)
	if err != nil {
		return "", "", "", err
	}

	idParts := strings.Split(strings.TrimPrefix(repoArn.Resource, "repository/"), "/")
	if len(idParts) != 2 {
		return "", "", "", fmt.Errorf("expected resource part of arn in format DomainName/RepositoryName, received: %s", repoArn.Resource)
	}
	return repoArn.AccountID, idParts[0], idParts[1], nil
}
<|endoftext|>


<commit_before>package main

import "fmt"

func twoSum(nums []int, target int) []int {
	size := len(nums)
	min := nums[0]
	for i := 0; i < size; i++ {
		if nums[i] < min {
			min = nums[i]
		}
	}
	max := target - min
	len := max - min + 1

	indexer := make([]int, len)
	for i := 0; i < len; i++ {
		indexer[i] = -1
	}

	ret := make([]int, 2)

	for i := 0; i < size; i++ {
		offset := nums[i] - min
		target_offset := target - nums[i] - min

		if offset < len {
			if indexer[target_offset] != -1 {
				ret[0] = i
				ret[1] = indexer[target_offset]
				break
			}
			indexer[offset] = i
		}
	}
	return ret
}

func main() {
	array := []int{123, 353, -3, 4, 11, 10, 6, 5, 9}
	target := 7

	result := twoSum(array, target)
	fmt.Println(result)
}
<commit_msg>twoSum<commit_after>package main

import "fmt"

/*
Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

*/

func twoSum(nums []int, target int) []int {
	size := len(nums)
	min := nums[0]
	for i := 0; i < size; i++ {
		if nums[i] < min {
			min = nums[i]
		}
	}
	max := target - min
	len := max - min + 1
	// 通过最小值，及target限定了最大值，缩小规模

	indexer := make([]int, len)
	for i := 0; i < len; i++ {
		indexer[i] = -1
	}
	// 空间换时间
	// indexer存的是每个值相对于min的offset到值在数组位置的映射

	ret := make([]int, 2)

	for i := 0; i < size; i++ {
		// 这个位置存到indexer的哪里
		offset := nums[i] - min
		// 与之相加等于target的目标值位置存到indexer的哪里
		target_offset := target - nums[i] - min

		if offset < len {
			// 这样如果要找的另一伴在的话，直接返回两者index
			if indexer[target_offset] != -1 {
				ret[0] = i
				ret[1] = indexer[target_offset]
				break
			}
			indexer[offset] = i
		}
	}
	return ret
}

func main() {
	array := []int{123, 353, -3, 4, 11, 10, 6, 5, 9}
	target := 7

	result := twoSum(array, target)
	fmt.Println(result)
}
<|endoftext|>


<commit_before>package instruments

import (
	"github.com/cloudfoundry-incubator/metricz/instrumentation"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
)

type taskInstrument struct {
	bbs bbs.MetricsBBS
}

func NewTaskInstrument(metricsBbs bbs.MetricsBBS) instrumentation.Instrumentable {
	return &taskInstrument{bbs: metricsBbs}
}

func (t *taskInstrument) Emit() instrumentation.Context {
	pendingCount := 0
	claimedCount := 0
	runningCount := 0
	completedCount := 0
	resolvingCount := 0

	allTasks, err := t.bbs.GetAllTasks()

	if err == nil {
		for _, runOnce := range allTasks {
			switch runOnce.State {
			case models.TaskStatePending:
				pendingCount++
			case models.TaskStateClaimed:
				claimedCount++
			case models.TaskStateRunning:
				runningCount++
			case models.TaskStateCompleted:
				completedCount++
			case models.TaskStateResolving:
				resolvingCount++
			}
		}
	} else {
		pendingCount = -1
		claimedCount = -1
		runningCount = -1
		completedCount = -1
		resolvingCount = -1
	}

	return instrumentation.Context{
		Name: "Tasks",
		Metrics: []instrumentation.Metric{
			{
				Name:  "Pending",
				Value: pendingCount,
			},
			{
				Name:  "Claimed",
				Value: claimedCount,
			},
			{
				Name:  "Running",
				Value: runningCount,
			},
			{
				Name:  "Completed",
				Value: completedCount,
			},
			{
				Name:  "Resolving",
				Value: resolvingCount,
			},
		},
	}
}
<commit_msg>runOnce -> task<commit_after>package instruments

import (
	"github.com/cloudfoundry-incubator/metricz/instrumentation"
	"github.com/cloudfoundry-incubator/runtime-schema/bbs"
	"github.com/cloudfoundry-incubator/runtime-schema/models"
)

type taskInstrument struct {
	bbs bbs.MetricsBBS
}

func NewTaskInstrument(metricsBbs bbs.MetricsBBS) instrumentation.Instrumentable {
	return &taskInstrument{bbs: metricsBbs}
}

func (t *taskInstrument) Emit() instrumentation.Context {
	pendingCount := 0
	claimedCount := 0
	runningCount := 0
	completedCount := 0
	resolvingCount := 0

	allTasks, err := t.bbs.GetAllTasks()

	if err == nil {
		for _, task := range allTasks {
			switch task.State {
			case models.TaskStatePending:
				pendingCount++
			case models.TaskStateClaimed:
				claimedCount++
			case models.TaskStateRunning:
				runningCount++
			case models.TaskStateCompleted:
				completedCount++
			case models.TaskStateResolving:
				resolvingCount++
			}
		}
	} else {
		pendingCount = -1
		claimedCount = -1
		runningCount = -1
		completedCount = -1
		resolvingCount = -1
	}

	return instrumentation.Context{
		Name: "Tasks",
		Metrics: []instrumentation.Metric{
			{
				Name:  "Pending",
				Value: pendingCount,
			},
			{
				Name:  "Claimed",
				Value: claimedCount,
			},
			{
				Name:  "Running",
				Value: runningCount,
			},
			{
				Name:  "Completed",
				Value: completedCount,
			},
			{
				Name:  "Resolving",
				Value: resolvingCount,
			},
		},
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/itchio/butler/cmd/apply"
	"github.com/itchio/butler/cmd/cave"
	"github.com/itchio/butler/cmd/clean"
	"github.com/itchio/butler/cmd/configure"
	"github.com/itchio/butler/cmd/cp"
	"github.com/itchio/butler/cmd/diff"
	"github.com/itchio/butler/cmd/ditto"
	"github.com/itchio/butler/cmd/dl"
	"github.com/itchio/butler/cmd/elevate"
	"github.com/itchio/butler/cmd/elfprops"
	"github.com/itchio/butler/cmd/exeprops"
	"github.com/itchio/butler/cmd/fetch"
	"github.com/itchio/butler/cmd/file"
	"github.com/itchio/butler/cmd/heal"
	"github.com/itchio/butler/cmd/indexzip"
	"github.com/itchio/butler/cmd/login"
	"github.com/itchio/butler/cmd/logout"
	"github.com/itchio/butler/cmd/ls"
	"github.com/itchio/butler/cmd/mkdir"
	"github.com/itchio/butler/cmd/msi"
	"github.com/itchio/butler/cmd/pipe"
	"github.com/itchio/butler/cmd/prereqs"
	"github.com/itchio/butler/cmd/probe"
	"github.com/itchio/butler/cmd/sign"
	"github.com/itchio/butler/cmd/sizeof"
	"github.com/itchio/butler/cmd/status"
	"github.com/itchio/butler/cmd/untar"
	"github.com/itchio/butler/cmd/unzip"
	"github.com/itchio/butler/cmd/upgrade"
	"github.com/itchio/butler/cmd/verify"
	"github.com/itchio/butler/cmd/version"
	"github.com/itchio/butler/cmd/walk"
	"github.com/itchio/butler/cmd/which"
	"github.com/itchio/butler/cmd/wipe"
	"github.com/itchio/butler/mansion"
)

// Each of these specify their own arguments and flags in
// their own package.
func registerCommands(ctx *mansion.Context) {
	version.Register(ctx)
	which.Register(ctx)

	login.Register(ctx)
	logout.Register(ctx)
	upgrade.Register(ctx)

	dl.Register(ctx)
	cp.Register(ctx)
	ls.Register(ctx)
	wipe.Register(ctx)
	sizeof.Register(ctx)
	mkdir.Register(ctx)
	ditto.Register(ctx)
	file.Register(ctx)
	probe.Register(ctx)

	clean.Register(ctx)
	walk.Register(ctx)

	sign.Register(ctx)
	diff.Register(ctx)
	apply.Register(ctx)
	verify.Register(ctx)
	heal.Register(ctx)

	status.Register(ctx)
	fetch.Register(ctx)

	msi.Register(ctx)
	prereqs.Register(ctx)

	unzip.Register(ctx)
	untar.Register(ctx)
	indexzip.Register(ctx)

	pipe.Register(ctx)
	elevate.Register(ctx)

	exeprops.Register(ctx)
	elfprops.Register(ctx)

	configure.Register(ctx)
	cave.Register(ctx)
}
<commit_msg>re-order commands to match pre-modular butler<commit_after>package main

import (
	"github.com/itchio/butler/cmd/apply"
	"github.com/itchio/butler/cmd/cave"
	"github.com/itchio/butler/cmd/clean"
	"github.com/itchio/butler/cmd/configure"
	"github.com/itchio/butler/cmd/cp"
	"github.com/itchio/butler/cmd/diff"
	"github.com/itchio/butler/cmd/ditto"
	"github.com/itchio/butler/cmd/dl"
	"github.com/itchio/butler/cmd/elevate"
	"github.com/itchio/butler/cmd/elfprops"
	"github.com/itchio/butler/cmd/exeprops"
	"github.com/itchio/butler/cmd/fetch"
	"github.com/itchio/butler/cmd/file"
	"github.com/itchio/butler/cmd/heal"
	"github.com/itchio/butler/cmd/indexzip"
	"github.com/itchio/butler/cmd/login"
	"github.com/itchio/butler/cmd/logout"
	"github.com/itchio/butler/cmd/ls"
	"github.com/itchio/butler/cmd/mkdir"
	"github.com/itchio/butler/cmd/msi"
	"github.com/itchio/butler/cmd/pipe"
	"github.com/itchio/butler/cmd/prereqs"
	"github.com/itchio/butler/cmd/probe"
	"github.com/itchio/butler/cmd/push"
	"github.com/itchio/butler/cmd/sign"
	"github.com/itchio/butler/cmd/sizeof"
	"github.com/itchio/butler/cmd/status"
	"github.com/itchio/butler/cmd/untar"
	"github.com/itchio/butler/cmd/unzip"
	"github.com/itchio/butler/cmd/upgrade"
	"github.com/itchio/butler/cmd/verify"
	"github.com/itchio/butler/cmd/version"
	"github.com/itchio/butler/cmd/walk"
	"github.com/itchio/butler/cmd/which"
	"github.com/itchio/butler/cmd/wipe"
	"github.com/itchio/butler/mansion"
)

// Each of these specify their own arguments and flags in
// their own package.
func registerCommands(ctx *mansion.Context) {
	// documented commands

	login.Register(ctx)
	logout.Register(ctx)

	push.Register(ctx)
	fetch.Register(ctx)
	status.Register(ctx)

	file.Register(ctx)
	ls.Register(ctx)

	which.Register(ctx)
	version.Register(ctx)
	upgrade.Register(ctx)

	sign.Register(ctx)
	verify.Register(ctx)
	diff.Register(ctx)
	apply.Register(ctx)
	heal.Register(ctx)

	// hidden commands

	dl.Register(ctx)
	cp.Register(ctx)
	wipe.Register(ctx)
	sizeof.Register(ctx)
	mkdir.Register(ctx)
	ditto.Register(ctx)
	probe.Register(ctx)

	clean.Register(ctx)
	walk.Register(ctx)

	msi.Register(ctx)
	prereqs.Register(ctx)

	unzip.Register(ctx)
	untar.Register(ctx)
	indexzip.Register(ctx)

	pipe.Register(ctx)
	elevate.Register(ctx)

	exeprops.Register(ctx)
	elfprops.Register(ctx)

	configure.Register(ctx)
	cave.Register(ctx)
}
<|endoftext|>


<commit_before>package hostess

import (
	// "errors"
	"fmt"
	"github.com/codegangsta/cli"
	"os"
)

func MaybeErrorln(c *cli.Context, message string) {
	if !c.Bool("q") {
		fmt.Printf("%s: %s\n", c.Command.Name, message)
	}
}

func MaybeError(c *cli.Context, message string) {
	if !c.Bool("q") {
		fmt.Printf("%s: %s\n", c.Command.Name, message)
	}
	os.Exit(1)
}

func MaybePrintln(c *cli.Context, message string) {
	if !c.Bool("s") {
		fmt.Println(message)
	}
}

func MaybeLoadHostFile(c *cli.Context) *Hostfile {
	hostsfile, errs := LoadHostFile()
	if len(errs) > 0 && !c.Bool("f") {
		for _, err := range errs {
			MaybeErrorln(c, err.Error())
		}
		MaybeError(c, "Errors while parsing hostsfile")
	}
	return hostsfile
}

func SprintEnabled(on bool) string {
	if on {
		return "(On)"
	} else {
		return "(Off)"
	}
}

func Add(c *cli.Context) {
	if len(c.Args()) != 2 {
		MaybeError(c, "expected <hostname> <ip>")
	}

	hostsfile := MaybeLoadHostFile(c)
	hostname := Hostname{c.Args()[0], c.Args()[1], true}
	err := hostsfile.Add(hostname)
	if err == nil {
		if c.Bool("n") {
			fmt.Println(hostsfile.Format())
		} else {
			MaybePrintln(c, fmt.Sprintf("Added %s -> %s %s", hostname.Domain, hostname.Ip, SprintEnabled(hostname.Enabled)))
			hostsfile.Save()
		}
	} else {
		MaybeError(c, err.Error())
	}
}

func Del(c *cli.Context) error {
	return nil
}

func Has(c *cli.Context) error {
	return nil
}

func Off(c *cli.Context) error {
	return nil
}

func On(c *cli.Context) error {
	return nil
}

func Ls(c *cli.Context) error {
	return nil
}

const fix_help = `Programmatically rewrite your hostsfile.

Domains pointing to the same IP will be consolidated, sorted, and extra
whitespace and comments will be removed.

   hostess fix      Rewrite the hostsfile
   hostess fix -n   Show the new hostsfile. Don't write it
`

func Fix(c *cli.Context) {
	hostfile := MaybeLoadHostFile(c)
	if c.Bool("n") {
		fmt.Println(hostfile.Format())
	} else {
		hostfile.Save()
	}
}

func Dump(c *cli.Context) error {
	return nil
}

func Apply(c *cli.Context) error {
	return nil
}
<commit_msg>Write errors to stderr instead of stdout<commit_after>package hostess

import (
	// "errors"
	"fmt"
	"github.com/codegangsta/cli"
	"os"
)

func MaybeErrorln(c *cli.Context, message string) {
	if !c.Bool("q") {
		os.Stderr.WriteString(fmt.Sprintf("%s: %s\n", c.Command.Name, message))
	}
}

func MaybeError(c *cli.Context, message string) {
	MaybeErrorln(c, message)
	os.Exit(1)
}

func MaybePrintln(c *cli.Context, message string) {
	if !c.Bool("s") {
		fmt.Println(message)
	}
}

func MaybeLoadHostFile(c *cli.Context) *Hostfile {
	hostsfile, errs := LoadHostFile()
	if len(errs) > 0 && !c.Bool("f") {
		for _, err := range errs {
			MaybeErrorln(c, err.Error())
		}
		MaybeError(c, "Errors while parsing hostsfile")
	}
	return hostsfile
}

func SprintEnabled(on bool) string {
	if on {
		return "(On)"
	} else {
		return "(Off)"
	}
}

func Add(c *cli.Context) {
	if len(c.Args()) != 2 {
		MaybeError(c, "expected <hostname> <ip>")
	}

	hostsfile := MaybeLoadHostFile(c)
	hostname := Hostname{c.Args()[0], c.Args()[1], true}
	err := hostsfile.Add(hostname)
	if err == nil {
		if c.Bool("n") {
			fmt.Println(hostsfile.Format())
		} else {
			MaybePrintln(c, fmt.Sprintf("Added %s -> %s %s", hostname.Domain, hostname.Ip, SprintEnabled(hostname.Enabled)))
			hostsfile.Save()
		}
	} else {
		MaybeError(c, err.Error())
	}
}

func Del(c *cli.Context) error {
	return nil
}

func Has(c *cli.Context) error {
	return nil
}

func Off(c *cli.Context) error {
	return nil
}

func On(c *cli.Context) error {
	return nil
}

func Ls(c *cli.Context) error {
	return nil
}

const fix_help = `Programmatically rewrite your hostsfile.

Domains pointing to the same IP will be consolidated, sorted, and extra
whitespace and comments will be removed.

   hostess fix      Rewrite the hostsfile
   hostess fix -n   Show the new hostsfile. Don't write it
`

func Fix(c *cli.Context) {
	hostfile := MaybeLoadHostFile(c)
	if c.Bool("n") {
		fmt.Println(hostfile.Format())
	} else {
		hostfile.Save()
	}
}

func Dump(c *cli.Context) error {
	return nil
}

func Apply(c *cli.Context) error {
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/serbe/ncp"
)

var (
	urls = []string{
		"/forum/viewforum.php?f=218", // Зарубежные Новинки (HD*Rip/LQ, DVDRip)
		"/forum/viewforum.php?f=221", // Отечественные Фильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=225", // Зарубежные Фильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=230", // Отечественные Мультфильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=231", // Зарубежные Мультфильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=270", // Отечественные Новинки (HD*Rip/LQ, DVDRip)
		"/forum/viewforum.php?f=319", // Зарубежная Классика (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=320", // Отечественная Классика (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
	}
)

func (a *App) get() error {
	var (
		err error
		i   int
	)
	for _, parseurl := range urls {
		topics, err := a.net.ParseForumTree(parseurl)
		if err != nil {
			log.Println("ParseForumTree ", parseurl, err)
			return err
		}
		for _, topic := range topics {
			_, err := a.getTorrentByHref(topic.Href)
			if err != nil {
				film, err := a.net.ParseTopic(topic)
				if err == nil {
					if film.Description != "" {
						i++
						film = a.checkName(film)
						_, err = a.createTorrent(film)
						if err != nil {
							log.Println("createTorrent ", err)
						}
					} else {
						log.Println("empty Description ", film.Href)
					}
				} else {
					log.Println("ParseTopic ", err)
				}
			}
		}
	}
	if i > 0 {
		log.Println("Adding", i, "new films")
	} else {
		log.Println("No adding new films")
	}
	return err
}

func (a *App) update() error {
	var (
		i        int
		err      error
		torrents []Torrent
	)

	torrents, err = a.getWithDownload()
	if err != nil {
		return err
	}
	for _, tor := range torrents {
		var topic ncp.Topic
		topic.Href = tor.Href
		f, err := a.net.ParseTopic(topic)
		if err == nil {
			if f.NNM != tor.NNM || f.Seeders != tor.Seeders || f.Leechers != tor.Leechers || f.Torrent != tor.Torrent {
				i++
				a.updateTorrent(tor.ID, f)
			}
		} else {
			return err
		}
	}
	if i > 0 {
		log.Println("Update", i, "movies")
	} else {
		log.Println("No movies update")
	}
	return nil
}

func (a *App) name() error {
	var i int
	movies, err := a.getMovies()
	if err != nil {
		return err
	}
	for _, movie := range movies {
		if movie.Name == strings.ToUpper(movie.Name) {
			lowerName, err := a.getUpperName(movie)
			if err == nil {
				i++
				a.updateName(movie.ID, lowerName)
			}
		}
	}
	if i > 0 {
		log.Println(i, "name fixed")
	} else {
		log.Println("No fixed names")
	}
	return nil
}

func (a *App) rating() error {
	var (
		i int
	)
	movies, err := a.getNoRatingMovies()
	if err != nil {
		return err
	}
	for _, movie := range movies {
		if movie.Kinopoisk == 0 || movie.IMDb == 0 || movie.Duration == "" {
			kp, err := a.getRating(movie)
			if err == nil {
				i++
				_ = a.updateRating(movie, kp)
			} else {
				if a.debug {
					log.Println("updateRating: ", err)
				}
			}
		}
	}
	if i > 0 {
		log.Println(i, "ratings update")
	} else {
		log.Println("No update ratings")
	}
	return nil
}

func (a *App) poster() error {
	var (
		i     int
		files []string
	)
	movies, err := a.getMovies()
	if err != nil {
		return err
	}
	filesInDir, _ := ioutil.ReadDir(a.hd)
	for _, file := range filesInDir {
		files = append(files, file.Name())
	}
	for _, movie := range movies {
		if movie.PosterURL != "" {
			if movie.Poster != "" {
				if !existsFile(a.hd + movie.Poster) {
					poster, err := a.getPoster(movie.PosterURL)
					if err == nil {
						i++
						err = a.updatePoster(movie, poster)
						if err != nil {
							log.Println("updatePoster ", poster, err)
						}
					} else {
						log.Println("getPoster ", poster, err)
					}
				} else {
					files = deleteFromSlice(files, movie.Poster)
				}
			} else {
				poster, err := a.getPoster(movie.PosterURL)
				if err == nil {
					i++
					_ = a.updatePoster(movie, poster)
				}
			}
		} else {
			tor, err := a.getTorrentByMovieID(movie.ID)
			if err == nil {
				var topic ncp.Topic
				topic.Href = tor.Href
				tempFilm, err := a.net.ParseTopic(topic)
				if err == nil {
					if tempFilm.Poster != "" {
						err = a.updatePosterURL(movie, tempFilm.Poster)
						if err == nil {
							poster, err := a.getPoster(tempFilm.Poster)
							if err == nil {
								i++
								_ = a.updatePoster(movie, poster)
							}
						}
					}
				}
			}
		}
	}
	for _, file := range files {
		_ = os.Remove(a.hd + file)
	}
	if i > 0 {
		log.Println(i, "posters update")
	} else {
		log.Println("No update posters")
	}
	if len(files) > 0 {
		log.Println("Remove", len(files), "unused images")
	}
	return nil
}
<commit_msg>add debug info<commit_after>package main

import (
	"io/ioutil"
	"log"
	"os"
	"strings"

	"github.com/serbe/ncp"
)

var (
	urls = []string{
		"/forum/viewforum.php?f=218", // Зарубежные Новинки (HD*Rip/LQ, DVDRip)
		"/forum/viewforum.php?f=221", // Отечественные Фильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=225", // Зарубежные Фильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=230", // Отечественные Мультфильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=231", // Зарубежные Мультфильмы (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=270", // Отечественные Новинки (HD*Rip/LQ, DVDRip)
		"/forum/viewforum.php?f=319", // Зарубежная Классика (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
		"/forum/viewforum.php?f=320", // Отечественная Классика (HD*Rip/LQ, DVDRip, SATRip, VHSRip)
	}
)

func (a *App) get() error {
	var (
		err error
		i   int
	)
	for _, parseurl := range urls {
		topics, err := a.net.ParseForumTree(parseurl)
		if err != nil {
			log.Println("ParseForumTree ", parseurl, err)
			return err
		}
		for _, topic := range topics {
			_, err := a.getTorrentByHref(topic.Href)
			if err != nil {
				film, err := a.net.ParseTopic(topic)
				if err == nil {
					if film.Description != "" {
						i++
						film = a.checkName(film)
						_, err = a.createTorrent(film)
						if err != nil {
							log.Println("createTorrent ", err)
						}
					} else {
						log.Println("empty Description ", film.Href)
					}
				} else {
					log.Println("ParseTopic ", err)
				}
			}
		}
	}
	if i > 0 {
		log.Println("Adding", i, "new films")
	} else {
		log.Println("No adding new films")
	}
	return err
}

func (a *App) update() error {
	var (
		i        int
		err      error
		torrents []Torrent
	)

	torrents, err = a.getWithDownload()
	if err != nil {
		return err
	}
	for _, tor := range torrents {
		var topic ncp.Topic
		topic.Href = tor.Href
		f, err := a.net.ParseTopic(topic)
		if err == nil {
			if f.NNM != tor.NNM || f.Seeders != tor.Seeders || f.Leechers != tor.Leechers || f.Torrent != tor.Torrent {
				i++
				a.updateTorrent(tor.ID, f)
			}
		} else {
			return err
		}
	}
	if i > 0 {
		log.Println("Update", i, "movies")
	} else {
		log.Println("No movies update")
	}
	return nil
}

func (a *App) name() error {
	var i int
	movies, err := a.getMovies()
	if err != nil {
		return err
	}
	for _, movie := range movies {
		if movie.Name == strings.ToUpper(movie.Name) {
			lowerName, err := a.getUpperName(movie)
			if err == nil {
				i++
				a.updateName(movie.ID, lowerName)
			}
		}
	}
	if i > 0 {
		log.Println(i, "name fixed")
	} else {
		log.Println("No fixed names")
	}
	return nil
}

func (a *App) rating() error {
	var (
		i int
	)
	movies, err := a.getNoRatingMovies()
	if err != nil {
		return err
	}
	for _, movie := range movies {
		if movie.Kinopoisk == 0 || movie.IMDb == 0 || movie.Duration == "" {
			kp, err := a.getRating(movie)
			if err == nil {
				i++
				_ = a.updateRating(movie, kp)
				if a.debug {
					log.Println(movie.Name, movie.EngName, movie.Year)
					log.Println(kp)
				}
			} else {
				if a.debug {
					log.Println(movie.Name, movie.EngName, movie.Year)
					log.Println("updateRating: ", err)
				}
			}
		}
	}
	if i > 0 {
		log.Println(i, "ratings update")
	} else {
		log.Println("No update ratings")
	}
	return nil
}

func (a *App) poster() error {
	var (
		i     int
		files []string
	)
	movies, err := a.getMovies()
	if err != nil {
		return err
	}
	filesInDir, _ := ioutil.ReadDir(a.hd)
	for _, file := range filesInDir {
		files = append(files, file.Name())
	}
	for _, movie := range movies {
		if movie.PosterURL != "" {
			if movie.Poster != "" {
				if !existsFile(a.hd + movie.Poster) {
					poster, err := a.getPoster(movie.PosterURL)
					if err == nil {
						i++
						err = a.updatePoster(movie, poster)
						if err != nil {
							log.Println("updatePoster ", poster, err)
						}
					} else {
						log.Println("getPoster ", poster, err)
					}
				} else {
					files = deleteFromSlice(files, movie.Poster)
				}
			} else {
				poster, err := a.getPoster(movie.PosterURL)
				if err == nil {
					i++
					_ = a.updatePoster(movie, poster)
				}
			}
		} else {
			tor, err := a.getTorrentByMovieID(movie.ID)
			if err == nil {
				var topic ncp.Topic
				topic.Href = tor.Href
				tempFilm, err := a.net.ParseTopic(topic)
				if err == nil {
					if tempFilm.Poster != "" {
						err = a.updatePosterURL(movie, tempFilm.Poster)
						if err == nil {
							poster, err := a.getPoster(tempFilm.Poster)
							if err == nil {
								i++
								_ = a.updatePoster(movie, poster)
							}
						}
					}
				}
			}
		}
	}
	for _, file := range files {
		_ = os.Remove(a.hd + file)
	}
	if i > 0 {
		log.Println(i, "posters update")
	} else {
		log.Println("No update posters")
	}
	if len(files) > 0 {
		log.Println("Remove", len(files), "unused images")
	}
	return nil
}
<|endoftext|>