<commit_before>/*
Copyright 2018 The Knative 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 duck

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

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/cache"

	"github.com/knative/pkg/apis"
)

// TypedInformerFactory implements InformerFactory such that the elements
// tracked by the informer/lister have the type of the canonical "obj".
type TypedInformerFactory struct {
	Client       dynamic.Interface
	Type         apis.Listable
	ResyncPeriod time.Duration
	StopChannel  <-chan struct{}
}

// Check that TypedInformerFactory implements InformerFactory.
var _ InformerFactory = (*TypedInformerFactory)(nil)

// Get implements InformerFactory.
func (dif *TypedInformerFactory) Get(gvr schema.GroupVersionResource) (cache.SharedIndexInformer, cache.GenericLister, error) {
	listObj := dif.Type.GetListType()
	lw := &cache.ListWatch{
		ListFunc:  asStructuredLister(dif.Client.Resource(gvr).List, listObj),
		WatchFunc: AsStructuredWatcher(dif.Client.Resource(gvr).Watch, dif.Type),
	}
	inf := cache.NewSharedIndexInformer(lw, dif.Type, dif.ResyncPeriod, cache.Indexers{
		cache.NamespaceIndex: cache.MetaNamespaceIndexFunc,
	})

	lister := cache.NewGenericLister(inf.GetIndexer(), gvr.GroupResource())

	go inf.Run(dif.StopChannel)

	if ok := cache.WaitForCacheSync(dif.StopChannel, inf.HasSynced); !ok {
		return nil, nil, fmt.Errorf("Failed starting shared index informer for %v with type %T", gvr, dif.Type)
	}

	return inf, lister, nil
}

type unstructuredLister func(metav1.ListOptions) (*unstructured.UnstructuredList, error)

func asStructuredLister(ulist unstructuredLister, listObj runtime.Object) cache.ListFunc {
	return func(opts metav1.ListOptions) (runtime.Object, error) {
		ul, err := ulist(opts)
		if err != nil {
			return nil, err
		}
		res := listObj.DeepCopyObject()
		if err := FromUnstructured(ul, res); err != nil {
			return nil, err
		}
		return res, nil
	}
}

// AsStructuredWatcher is public for testing only.
// TODO(mattmoor): Move tests for this to `package duck` and make private.
func AsStructuredWatcher(wf cache.WatchFunc, obj runtime.Object) cache.WatchFunc {
	return func(lo metav1.ListOptions) (watch.Interface, error) {
		uw, err := wf(lo)
		if err != nil {
			return nil, err
		}
		structuredCh := make(chan watch.Event)
		go func() {
			defer close(structuredCh)
			unstructuredCh := uw.ResultChan()
			for {
				select {
				case ue, ok := <-unstructuredCh:
					if !ok {
						// Channel is closed.
						return
					}

					unstructuredObj, ok := ue.Object.(*unstructured.Unstructured)
					if !ok {
						// If it isn't an unstructured object, then forward the
						// event as-is.  This is likely to happen when the event's
						// Type is an Error.
						structuredCh <- ue
						continue
					}
					structuredObj := obj.DeepCopyObject()

					err := FromUnstructured(unstructuredObj, structuredObj)
					if err != nil {
						// Pass back an error indicating that the object we got
						// was invalid.
						structuredCh <- watch.Event{
							Type: watch.Error,
							Object: &metav1.Status{
								Status:  metav1.StatusFailure,
								Code:    http.StatusUnprocessableEntity,
								Reason:  metav1.StatusReasonInvalid,
								Message: err.Error(),
							},
						}
						continue
					}
					// Send the structured event.
					structuredCh <- watch.Event{
						Type:   ue.Type,
						Object: structuredObj,
					}
				}
			}
		}()

		return NewProxyWatcher(structuredCh), nil
	}
}
<commit_msg>Better for loop for iterating over the channel (#458)<commit_after>/*
Copyright 2018 The Knative 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 duck

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

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/dynamic"
	"k8s.io/client-go/tools/cache"

	"github.com/knative/pkg/apis"
)

// TypedInformerFactory implements InformerFactory such that the elements
// tracked by the informer/lister have the type of the canonical "obj".
type TypedInformerFactory struct {
	Client       dynamic.Interface
	Type         apis.Listable
	ResyncPeriod time.Duration
	StopChannel  <-chan struct{}
}

// Check that TypedInformerFactory implements InformerFactory.
var _ InformerFactory = (*TypedInformerFactory)(nil)

// Get implements InformerFactory.
func (dif *TypedInformerFactory) Get(gvr schema.GroupVersionResource) (cache.SharedIndexInformer, cache.GenericLister, error) {
	listObj := dif.Type.GetListType()
	lw := &cache.ListWatch{
		ListFunc:  asStructuredLister(dif.Client.Resource(gvr).List, listObj),
		WatchFunc: AsStructuredWatcher(dif.Client.Resource(gvr).Watch, dif.Type),
	}
	inf := cache.NewSharedIndexInformer(lw, dif.Type, dif.ResyncPeriod, cache.Indexers{
		cache.NamespaceIndex: cache.MetaNamespaceIndexFunc,
	})

	lister := cache.NewGenericLister(inf.GetIndexer(), gvr.GroupResource())

	go inf.Run(dif.StopChannel)

	if ok := cache.WaitForCacheSync(dif.StopChannel, inf.HasSynced); !ok {
		return nil, nil, fmt.Errorf("Failed starting shared index informer for %v with type %T", gvr, dif.Type)
	}

	return inf, lister, nil
}

type unstructuredLister func(metav1.ListOptions) (*unstructured.UnstructuredList, error)

func asStructuredLister(ulist unstructuredLister, listObj runtime.Object) cache.ListFunc {
	return func(opts metav1.ListOptions) (runtime.Object, error) {
		ul, err := ulist(opts)
		if err != nil {
			return nil, err
		}
		res := listObj.DeepCopyObject()
		if err := FromUnstructured(ul, res); err != nil {
			return nil, err
		}
		return res, nil
	}
}

// AsStructuredWatcher is public for testing only.
// TODO(mattmoor): Move tests for this to `package duck` and make private.
func AsStructuredWatcher(wf cache.WatchFunc, obj runtime.Object) cache.WatchFunc {
	return func(lo metav1.ListOptions) (watch.Interface, error) {
		uw, err := wf(lo)
		if err != nil {
			return nil, err
		}
		structuredCh := make(chan watch.Event)
		go func() {
			defer close(structuredCh)
			unstructuredCh := uw.ResultChan()
			for ue := range unstructuredCh {
				unstructuredObj, ok := ue.Object.(*unstructured.Unstructured)
				if !ok {
					// If it isn't an unstructured object, then forward the
					// event as-is.  This is likely to happen when the event's
					// Type is an Error.
					structuredCh <- ue
					continue
				}
				structuredObj := obj.DeepCopyObject()

				err := FromUnstructured(unstructuredObj, structuredObj)
				if err != nil {
					// Pass back an error indicating that the object we got
					// was invalid.
					structuredCh <- watch.Event{
						Type: watch.Error,
						Object: &metav1.Status{
							Status:  metav1.StatusFailure,
							Code:    http.StatusUnprocessableEntity,
							Reason:  metav1.StatusReasonInvalid,
							Message: err.Error(),
						},
					}
					continue
				}
				// Send the structured event.
				structuredCh <- watch.Event{
					Type:   ue.Type,
					Object: structuredObj,
				}
			}
		}()

		return NewProxyWatcher(structuredCh), nil
	}
}
<|endoftext|>


<commit_before>package panos

import (
	"bytes"
	"crypto/tls"
	"encoding/xml"
	"fmt"
	"github.com/scottdware/go-rested"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

// Wildfire contains information about our session.
type Wildfire struct {
	APIKey string
	URL    string
}

// wildfireError contains any error message we recieve.
type wildfireError struct {
	XMLName xml.Name `xml:"error"`
	Message string   `xml:"error-message"`
}

// NewWildfireSession establishes a new session to your Wildfire account.
func NewWildfireSession(apikey string) *Wildfire {
	return &Wildfire{
		APIKey: apikey,
		URL:    "https://wildfire.paloaltonetworks.com/publicapi/",
	}
}

// SubmitFile submits a file to Wildfire for analyzing.
func (w *Wildfire) SubmitFile(file string) error {
	var b bytes.Buffer
	mwriter := multipart.NewWriter(&b)
	uri := fmt.Sprintf("%ssubmit/file", w.URL)
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}

	f, err := os.Open(file)
	if err != nil {
		return err
	}

	fw, err := mwriter.CreateFormFile("file", file)
	if err != nil {
		return err
	}

	if _, err := io.Copy(fw, f); err != nil {
		return err
	}

	if fw, err = mwriter.CreateFormField("apikey"); err != nil {
		return err
	}

	if _, err = fw.Write([]byte(w.APIKey)); err != nil {
		return err
	}

	mwriter.Close()

	req, err := http.NewRequest("POST", uri, &b)
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", mwriter.FormDataContentType())
	res, err := client.Do(req)
	if err != nil {
		return err
	}

	if res.Status != "200 OK" {
		return fmt.Errorf("file submission error: %s", res.Status)
	}

	return nil
}

// SubmitURL submits a URL to Wildfire for analyzing.
func (w *Wildfire) SubmitURL(url string) error {
	r := rested.NewRequest()
	uri := fmt.Sprintf("%ssubmit/url", w.URL)

	form := map[string]string{
		"url":    url,
		"apikey": w.APIKey,
	}

	resp := r.Send("post", uri, form, nil, nil)
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

// GetReport retrieves the report on the given file hash (MD5, SHA-1 or SHA-256), and returns the output in XML format.
func (w *Wildfire) GetReport(hash, format string) (string, error) {
	r := rested.NewRequest()
	uri := fmt.Sprintf("%sget/report", w.URL)
	form := map[string]string{
		"hash":   hash,
		"format": format,
		"apikey": w.APIKey,
	}

	resp := r.Send("post", uri, form, nil, nil)
	if resp.Error != nil {
		return "", resp.Error
	}

	return string(resp.Body), nil
}
<commit_msg>Removed option to specify report format<commit_after>package panos

import (
	"bytes"
	"crypto/tls"
	"encoding/xml"
	"fmt"
	"github.com/scottdware/go-rested"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

// Wildfire contains information about our session.
type Wildfire struct {
	APIKey string
	URL    string
}

// wildfireError contains any error message we recieve.
type wildfireError struct {
	XMLName xml.Name `xml:"error"`
	Message string   `xml:"error-message"`
}

// NewWildfireSession establishes a new session to your Wildfire account.
func NewWildfireSession(apikey string) *Wildfire {
	return &Wildfire{
		APIKey: apikey,
		URL:    "https://wildfire.paloaltonetworks.com/publicapi/",
	}
}

// SubmitFile submits a file to Wildfire for analyzing.
func (w *Wildfire) SubmitFile(file string) error {
	var b bytes.Buffer
	mwriter := multipart.NewWriter(&b)
	uri := fmt.Sprintf("%ssubmit/file", w.URL)
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}

	f, err := os.Open(file)
	if err != nil {
		return err
	}

	fw, err := mwriter.CreateFormFile("file", file)
	if err != nil {
		return err
	}

	if _, err := io.Copy(fw, f); err != nil {
		return err
	}

	if fw, err = mwriter.CreateFormField("apikey"); err != nil {
		return err
	}

	if _, err = fw.Write([]byte(w.APIKey)); err != nil {
		return err
	}

	mwriter.Close()

	req, err := http.NewRequest("POST", uri, &b)
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", mwriter.FormDataContentType())
	res, err := client.Do(req)
	if err != nil {
		return err
	}

	if res.Status != "200 OK" {
		return fmt.Errorf("file submission error: %s", res.Status)
	}

	return nil
}

// SubmitURL submits a URL to Wildfire for analyzing.
func (w *Wildfire) SubmitURL(url string) error {
	r := rested.NewRequest()
	uri := fmt.Sprintf("%ssubmit/url", w.URL)

	form := map[string]string{
		"url":    url,
		"apikey": w.APIKey,
	}

	resp := r.Send("post", uri, form, nil, nil)
	if resp.Error != nil {
		return resp.Error
	}

	return nil
}

// GetReport retrieves the report on the given file hash (MD5, SHA-1 or SHA-256), and returns the output in XML format.
func (w *Wildfire) GetReport(hash string) (string, error) {
	r := rested.NewRequest()
	uri := fmt.Sprintf("%sget/report", w.URL)
	form := map[string]string{
		"hash":   hash,
		"format": "xml",
		"apikey": w.APIKey,
	}

	resp := r.Send("post", uri, form, nil, nil)
	if resp.Error != nil {
		return "", resp.Error
	}

	return string(resp.Body), nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"strings"
	"time"

	trello "github.com/jnormington/go-trello"
	dropbox "github.com/tj/go-dropbox"
)

var dateLayout = "2006-01-02T15:04:05.000Z"

// Card holds all the attributes needed for migrating a complete card from Trello to Clubhouse
type Card struct {
	Name        string            `json:"name"`
	Desc        string            `json:"desc"`
	Labels      []string          `json:"labels"`
	DueDate     *time.Time        `json:"due_date"`
	Creator     string            `json:"card_creator"`
	CreatedAt   *time.Time        `json:"created_at"`
	Comments    []Comment         `json:"comments"`
	Tasks       []Task            `json:"checklists"`
	Position    float32           `json:"position"`
	ShortURL    string            `json:"url"`
	Attachments map[string]string `json:"attachments"`
}

// Task builds a basic object based off trello.Task
type Task struct {
	Completed   bool   `json:"completed"`
	Description string `json:"description"`
}

// Comment builds a basic object based off trello.Comment
type Comment struct {
	Text      string
	Creator   string
	CreatedAt *time.Time
}

// ProcessCardsForExporting takes *[]trello.Card, *TrelloOptions and builds up a Card
// which consists of calling other functions to make the api calls to Trello
// for the relevant attributes of a card returns *[]Card
func ProcessCardsForExporting(crds *[]trello.Card, opts *TrelloOptions) *[]Card {
	var cards []Card

	for _, card := range *crds {
		var c Card

		c.Name = card.Name
		c.Desc = card.Desc
		c.Labels = getLabelsFlattenFromCard(&card)
		c.DueDate = parseDateOrReturnNil(card.Due)
		c.Creator, c.CreatedAt, c.Comments = getCommentsAndCardCreator(&card)
		c.Tasks = getCheckListsForCard(&card)
		c.Position = card.Pos
		c.ShortURL = card.ShortUrl

		if opts.ProcessImages {
			c.Attachments = downloadCardAttachmentsUploadToDropbox(&card)
		}

		cards = append(cards, c)
	}

	return &cards
}

func getCommentsAndCardCreator(card *trello.Card) (string, *time.Time, []Comment) {
	var creator string
	var createdAt *time.Time
	var comments []Comment

	actions, err := card.Actions()
	if err != nil {
		fmt.Println("Error: Querying the actions for:", card.Name, "ignoring...", err)
	}

	for _, a := range actions {
		if a.Type == "commentCard" && a.Data.Text != "" {
			c := Comment{
				Text:      a.Data.Text,
				Creator:   a.MemberCreator.FullName,
				CreatedAt: parseDateOrReturnNil(a.Date),
			}
			comments = append(comments, c)

		} else if a.Type == "createCard" {
			creator = a.MemberCreator.FullName
			createdAt = parseDateOrReturnNil(a.Date)
		}
	}

	return creator, createdAt, comments
}

func getCheckListsForCard(card *trello.Card) []Task {
	var tasks []Task

	checklists, err := card.Checklists()
	if err != nil {
		fmt.Println("Error: Occurred querying checklists for:", card.Name, "ignoring...", err)
	}

	for _, cl := range checklists {
		for _, i := range cl.CheckItems {
			var completed bool
			if i.State == "complete" {
				completed = true
			}

			t := Task{
				Completed:   completed,
				Description: fmt.Sprintf("%s - %s", cl.Name, i.Name),
			}

			tasks = append(tasks, t)
		}
	}

	return tasks
}

func getLabelsFlattenFromCard(card *trello.Card) []string {
	var labels []string

	for _, l := range card.Labels {
		labels = append(labels, l.Name)
	}

	return labels
}

func parseDateOrReturnNil(strDate string) *time.Time {
	d, err := time.Parse(dateLayout, strDate)
	if err != nil {
		//If the date isn't parseable from trello api just return nil
		return nil
	}

	return &d
}

func downloadCardAttachmentsUploadToDropbox(card *trello.Card) map[string]string {
	sharedLinks := map[string]string{}
	d := dropbox.New(dropbox.NewConfig(dropboxToken))

	attachments, err := card.Attachments()
	if err != nil {
		log.Fatal(err)
	}

	for i, f := range attachments {
		name := strings.Replace(f.Name, " ", "", 10)
		path := fmt.Sprintf("/trello/%s/%s/%d%s%s", card.IdList, card.Id, i, "_", name)

		io := downloadTrelloAttachment(&f)
		_, err := d.Files.Upload(&dropbox.UploadInput{
			Path:   path,
			Mode:   dropbox.WriteModeAdd,
			Reader: io,
			Mute:   true,
		})

		io.Close()

		if err != nil {
			fmt.Printf("Error occurred uploading file to dropbox continuing... %s\n", err)
		} else {
			// Must be success created a shared url
			s := dropbox.CreateSharedLinkInput{path, false}
			out, err := d.Sharing.CreateSharedLink(&s)
			if err != nil {
				fmt.Printf("Error occurred sharing file on dropbox continuing... %s\n", err)
			} else {
				sharedLinks[name] = out.URL
			}
		}
	}

	return sharedLinks
}

func downloadTrelloAttachment(attachment *trello.Attachment) io.ReadCloser {
	resp, err := http.Get(attachment.Url)
	//	defer resp.Body.Close()

	if err != nil {
		log.Fatalf("Error in download Trello attachment %s\n", err)
	}

	return resp.Body
}
<commit_msg>Fix go-trello lib attachment wrong mimetype and url safe filenames when uploading to dropbox<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"regexp"
	"time"

	trello "github.com/jnormington/go-trello"
	dropbox "github.com/tj/go-dropbox"
)

var dateLayout = "2006-01-02T15:04:05.000Z"
var safeFileNameRegexp = regexp.MustCompile(`[^a-zA-Z0-9_.]+`)

// Card holds all the attributes needed for migrating a complete card from Trello to Clubhouse
type Card struct {
	Name        string            `json:"name"`
	Desc        string            `json:"desc"`
	Labels      []string          `json:"labels"`
	DueDate     *time.Time        `json:"due_date"`
	Creator     string            `json:"card_creator"`
	CreatedAt   *time.Time        `json:"created_at"`
	Comments    []Comment         `json:"comments"`
	Tasks       []Task            `json:"checklists"`
	Position    float32           `json:"position"`
	ShortURL    string            `json:"url"`
	Attachments map[string]string `json:"attachments"`
}

// Task builds a basic object based off trello.Task
type Task struct {
	Completed   bool   `json:"completed"`
	Description string `json:"description"`
}

// Comment builds a basic object based off trello.Comment
type Comment struct {
	Text      string
	Creator   string
	CreatedAt *time.Time
}

// ProcessCardsForExporting takes *[]trello.Card, *TrelloOptions and builds up a Card
// which consists of calling other functions to make the api calls to Trello
// for the relevant attributes of a card returns *[]Card
func ProcessCardsForExporting(crds *[]trello.Card, opts *TrelloOptions) *[]Card {
	var cards []Card

	for _, card := range *crds {
		var c Card

		c.Name = card.Name
		c.Desc = card.Desc
		c.Labels = getLabelsFlattenFromCard(&card)
		c.DueDate = parseDateOrReturnNil(card.Due)
		c.Creator, c.CreatedAt, c.Comments = getCommentsAndCardCreator(&card)
		c.Tasks = getCheckListsForCard(&card)
		c.Position = card.Pos
		c.ShortURL = card.ShortUrl

		if opts.ProcessImages {
			c.Attachments = downloadCardAttachmentsUploadToDropbox(&card)
		}

		cards = append(cards, c)
	}

	return &cards
}

func getCommentsAndCardCreator(card *trello.Card) (string, *time.Time, []Comment) {
	var creator string
	var createdAt *time.Time
	var comments []Comment

	actions, err := card.Actions()
	if err != nil {
		fmt.Println("Error: Querying the actions for:", card.Name, "ignoring...", err)
	}

	for _, a := range actions {
		if a.Type == "commentCard" && a.Data.Text != "" {
			c := Comment{
				Text:      a.Data.Text,
				Creator:   a.MemberCreator.FullName,
				CreatedAt: parseDateOrReturnNil(a.Date),
			}
			comments = append(comments, c)

		} else if a.Type == "createCard" {
			creator = a.MemberCreator.FullName
			createdAt = parseDateOrReturnNil(a.Date)
		}
	}

	return creator, createdAt, comments
}

func getCheckListsForCard(card *trello.Card) []Task {
	var tasks []Task

	checklists, err := card.Checklists()
	if err != nil {
		fmt.Println("Error: Occurred querying checklists for:", card.Name, "ignoring...", err)
	}

	for _, cl := range checklists {
		for _, i := range cl.CheckItems {
			var completed bool
			if i.State == "complete" {
				completed = true
			}

			t := Task{
				Completed:   completed,
				Description: fmt.Sprintf("%s - %s", cl.Name, i.Name),
			}

			tasks = append(tasks, t)
		}
	}

	return tasks
}

func getLabelsFlattenFromCard(card *trello.Card) []string {
	var labels []string

	for _, l := range card.Labels {
		labels = append(labels, l.Name)
	}

	return labels
}

func parseDateOrReturnNil(strDate string) *time.Time {
	d, err := time.Parse(dateLayout, strDate)
	if err != nil {
		//If the date isn't parseable from trello api just return nil
		return nil
	}

	return &d
}

func downloadCardAttachmentsUploadToDropbox(card *trello.Card) map[string]string {
	sharedLinks := map[string]string{}
	d := dropbox.New(dropbox.NewConfig(dropboxToken))

	attachments, err := card.Attachments()
	if err != nil {
		log.Fatal(err)
	}

	for i, f := range attachments {
		name := safeFileNameRegexp.ReplaceAllString(f.Name, "_")
		path := fmt.Sprintf("/trello/%s/%s/%d%s%s", card.IdList, card.Id, i, "_", name)

		io := downloadTrelloAttachment(&f)
		_, err := d.Files.Upload(&dropbox.UploadInput{
			Path:   path,
			Mode:   dropbox.WriteModeAdd,
			Reader: io,
			Mute:   true,
		})

		io.Close()

		if err != nil {
			fmt.Printf("Error occurred uploading file to dropbox continuing... %s\n", err)
		} else {
			// Must be success created a shared url
			s := dropbox.CreateSharedLinkInput{path, false}
			out, err := d.Sharing.CreateSharedLink(&s)
			if err != nil {
				fmt.Printf("Error occurred sharing file on dropbox continuing... %s\n", err)
			} else {
				sharedLinks[name] = out.URL
			}
		}
	}

	return sharedLinks
}

func downloadTrelloAttachment(attachment *trello.Attachment) io.ReadCloser {
	resp, err := http.Get(attachment.Url)
	//	defer resp.Body.Close()

	if err != nil {
		log.Fatalf("Error in download Trello attachment %s\n", err)
	}

	return resp.Body
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"time"

	"image"
	"image/jpeg"
	"image/png"
	"workshop/blog"
	"workshop/storage"

	"github.com/nfnt/resize"
)

// Storage is a structure of blog post
type Storage struct {
	ID       int
	Title    string
	Body     string
	CreateAt string
	Picture  string
}

// BlogStorage will store blog posts
var BlogStorage storage.Storage

// render is a function to render template
func render(w http.ResponseWriter, sTemplateName string, data map[string]interface{}) {

	// all templates are in a view folder.
	// we reference them by their names
	sNewTemplateName := "./view/" + sTemplateName + ".tpl"
	t, err := template.New("layout").ParseFiles("./view/layout.tpl", sNewTemplateName)

	if sTemplateName == "edit" || sTemplateName == "post" {
		t, err = t.ParseFiles("./view/form.tpl")
	}

	if err != nil {
		fmt.Println(w, "Error\n", err.Error())
	}

	err = t.ExecuteTemplate(w, "layout", data)
	if err != nil {
		fmt.Println(w, "Error\n", err.Error())
	}

}

// isError is a function to handle errors
func isError(err error, w http.ResponseWriter) bool {
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Server Error", http.StatusInternalServerError)
		return true
	}
	return false
}

// handlePost is a method which handle requests
// associated with blog entry creation
func handlerPost(w http.ResponseWriter, r *http.Request) {

	switch r.Method {
	case "GET":
		data := make(map[string]interface{})
		data["PageTitle"] = "Create new post"
		data["action"] = "create"
		render(w, "post", data)

	case "POST":

		switch r.FormValue("action") {
		case "create":
			createAt := time.Now().Format(time.RFC822) // time format into string
			id := BlogStorage.GetLength() + 1
			title := r.FormValue("title")
			body := r.FormValue("body")

			entry := blog.Entry{ID: id, Title: title, Body: body, CreateAt: createAt}
			entryID := BlogStorage.Add(entry) // we created entry, now we can save it

			r.ParseMultipartForm(4096 * 10) // how many bytes of image will be stored in memory
			f, fh, err := r.FormFile("picture")
			if err != nil {
				log.Println(BlogStorage.GetAll())
				http.Redirect(w, r, "/", http.StatusFound)
				return
			}

			ext := ""
			switch fh.Header.Get("Content-Type") {
			case "image/png":
				ext = "png"
			case "image/jpeg":
				ext = "jpeg"
			}

			// here we are creating random file name
			randBytes := make([]byte, 16)
			rand.Read(randBytes)
			filename := filepath.Join(hex.EncodeToString(randBytes)) + "." + ext
			fdesc, err := os.Create("./img/" + filename)
			if isError(err, w) {
				return
			}

			// after successfull creation we copy our image to this file
			io.Copy(fdesc, f)
			fdesc.Close()
			f.Close()

			// after successfull save of image to file,
			// we update our created entry
			entry.Picture = filename
			BlogStorage.Update(entryID, entry)

			sImageType := ""
			switch fh.Header.Get("Content-Type") {
			case "image/png":
				sImageType = "png"
			case "image/jpeg":
				sImageType = "jpeg"
			}

			// here we are making three files
			// of different sizes from original image
			for i := 2; i <= 3; i++ {
				// here we are using goroutines to do resize operation concurrently
				go func(divider int, sOriginalFile string, sType string, w http.ResponseWriter) {

					file, err := os.Open("./img/" + sOriginalFile)
					if isError(err, w) {
						return
					}

					// decode jpeg into image.Image
					var (
						img  image.Image
						conf image.Config
					)
					switch sType {
					case "jpeg":
						// when we decoded config, our bytes shifted
						conf, err = jpeg.DecodeConfig(file)
						if isError(err, w) {
							return
						}
						// so we need to return them back
						file.Seek(0, 0)
						img, err = jpeg.Decode(file)
						if isError(err, w) {
							return
						}
					case "png":
						img, err = png.Decode(file)
						if isError(err, w) {
							return
						}
						file.Seek(0, 0)
						conf, err = png.DecodeConfig(file)
						if isError(err, w) {
							return
						}

					}
					file.Close()

					// resize to width / divider using Lanczos resampling
					// and preserve aspect ratio
					m := resize.Resize(uint(conf.Width/divider), 0, img, resize.Lanczos3)

					out, err := os.Create("./img/" + strconv.Itoa(divider) + "_" + sOriginalFile)
					if isError(err, w) {
						return
					}
					defer out.Close()

					// write new image to file
					switch sType {
					case "jpeg":
						jpeg.Encode(out, m, nil)
					case "png":
						png.Encode(out, m)
					}
				}(i, filename, sImageType, w)
			}

		case "edit":
			var (
				err error
				id  int
			)

			if id, err = strconv.Atoi(r.FormValue("id")); err != nil {
				log.Println(err)
				http.Error(w, "ID not found", 404)
				return
			}

			entry, err := BlogStorage.GetByID(id)
			if err != nil {
				http.Error(w, "ID not found", 404)
				return
			}

			entry.Body = r.FormValue("body")
			entry.Title = r.FormValue("title")

			BlogStorage.Update(entry.ID, entry)

		}
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}

}

// handlerEdit handle blog entry edit request
func handlerEdit(w http.ResponseWriter, r *http.Request) {

	validPath := regexp.MustCompile("^/(edit)/([a-zA-Z0-9]+)$")
	m := validPath.FindStringSubmatch(r.URL.Path)
	if len(m) < 2 {
		http.NotFound(w, r)
		return
	}

	id := 0
	var err error
	if id, err = strconv.Atoi(m[2]); err != nil {
		http.NotFound(w, r)
		return
	}

	entry, err := BlogStorage.GetByID(id)
	if isError(err, w) {
		http.NotFound(w, r)
		return

	}

	data := make(map[string]interface{})
	data["PageTitle"] = "Edit"
	data["title"] = entry.Title
	data["body"] = entry.Body
	data["id"] = id
	data["action"] = "edit"
	render(w, "post", data)
}

func main() {

	log.Println("We ready to start")

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		data := make(map[string]interface{})
		data["PageTitle"] = "Workshop blog"
		data["storage"] = BlogStorage.GetAll()
		render(w, "main", data)
	})

	http.HandleFunc("/edit/", handlerEdit)
	http.HandleFunc("/post", handlerPost)

	http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("./img/"))))

	log.Fatal(http.ListenAndServe(":9000", nil))
}
<commit_msg>remove unnecessary code<commit_after>package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"time"

	"image"
	"image/jpeg"
	"image/png"
	"workshop/blog"
	"workshop/storage"

	"github.com/nfnt/resize"
)

// BlogStorage will store blog posts
var BlogStorage storage.Storage

// render is a function to render template
func render(w http.ResponseWriter, sTemplateName string, data map[string]interface{}) {

	// all templates are in a view folder.
	// we reference them by their names
	sNewTemplateName := "./view/" + sTemplateName + ".tpl"
	t, err := template.New("layout").ParseFiles("./view/layout.tpl", sNewTemplateName)

	if sTemplateName == "edit" || sTemplateName == "post" {
		t, err = t.ParseFiles("./view/form.tpl")
	}

	if err != nil {
		fmt.Println(w, "Error\n", err.Error())
	}

	err = t.ExecuteTemplate(w, "layout", data)
	if err != nil {
		fmt.Println(w, "Error\n", err.Error())
	}

}

// isError is a function to handle errors
func isError(err error, w http.ResponseWriter) bool {
	if err != nil {
		log.Println(err.Error())
		http.Error(w, "Server Error", http.StatusInternalServerError)
		return true
	}
	return false
}

// handlePost is a method which handle requests
// associated with blog entry creation
func handlerPost(w http.ResponseWriter, r *http.Request) {

	switch r.Method {
	case "GET":
		data := make(map[string]interface{})
		data["PageTitle"] = "Create new post"
		data["action"] = "create"
		render(w, "post", data)

	case "POST":

		switch r.FormValue("action") {
		case "create":
			createAt := time.Now().Format(time.RFC822) // time format into string
			id := BlogStorage.GetLength() + 1
			title := r.FormValue("title")
			body := r.FormValue("body")

			entry := blog.Entry{ID: id, Title: title, Body: body, CreateAt: createAt}
			entryID := BlogStorage.Add(entry) // we created entry, now we can save it

			r.ParseMultipartForm(4096 * 10) // how many bytes of image will be stored in memory
			f, fh, err := r.FormFile("picture")
			if err != nil {
				log.Println(BlogStorage.GetAll())
				http.Redirect(w, r, "/", http.StatusFound)
				return
			}

			ext := ""
			switch fh.Header.Get("Content-Type") {
			case "image/png":
				ext = "png"
			case "image/jpeg":
				ext = "jpeg"
			}

			// here we are creating random file name
			randBytes := make([]byte, 16)
			rand.Read(randBytes)
			filename := filepath.Join(hex.EncodeToString(randBytes)) + "." + ext
			fdesc, err := os.Create("./img/" + filename)
			if isError(err, w) {
				return
			}

			// after successfull creation we copy our image to this file
			io.Copy(fdesc, f)
			fdesc.Close()
			f.Close()

			// after successfull save of image to file,
			// we update our created entry
			entry.Picture = filename
			BlogStorage.Update(entryID, entry)

			sImageType := ""
			switch fh.Header.Get("Content-Type") {
			case "image/png":
				sImageType = "png"
			case "image/jpeg":
				sImageType = "jpeg"
			}

			// here we are making three files
			// of different sizes from original image
			for i := 2; i <= 3; i++ {
				// here we are using goroutines to do resize operation concurrently
				go func(divider int, sOriginalFile string, sType string, w http.ResponseWriter) {

					file, err := os.Open("./img/" + sOriginalFile)
					if isError(err, w) {
						return
					}

					// decode jpeg into image.Image
					var (
						img  image.Image
						conf image.Config
					)
					switch sType {
					case "jpeg":
						// when we decoded config, our bytes shifted
						conf, err = jpeg.DecodeConfig(file)
						if isError(err, w) {
							return
						}
						// so we need to return them back
						file.Seek(0, 0)
						img, err = jpeg.Decode(file)
						if isError(err, w) {
							return
						}
					case "png":
						img, err = png.Decode(file)
						if isError(err, w) {
							return
						}
						file.Seek(0, 0)
						conf, err = png.DecodeConfig(file)
						if isError(err, w) {
							return
						}

					}
					file.Close()

					// resize to width / divider using Lanczos resampling
					// and preserve aspect ratio
					m := resize.Resize(uint(conf.Width/divider), 0, img, resize.Lanczos3)

					out, err := os.Create("./img/" + strconv.Itoa(divider) + "_" + sOriginalFile)
					if isError(err, w) {
						return
					}
					defer out.Close()

					// write new image to file
					switch sType {
					case "jpeg":
						jpeg.Encode(out, m, nil)
					case "png":
						png.Encode(out, m)
					}
				}(i, filename, sImageType, w)
			}

		case "edit":
			var (
				err error
				id  int
			)

			if id, err = strconv.Atoi(r.FormValue("id")); err != nil {
				log.Println(err)
				http.Error(w, "ID not found", 404)
				return
			}

			entry, err := BlogStorage.GetByID(id)
			if err != nil {
				http.Error(w, "ID not found", 404)
				return
			}

			entry.Body = r.FormValue("body")
			entry.Title = r.FormValue("title")

			BlogStorage.Update(entry.ID, entry)

		}
		http.Redirect(w, r, "/", http.StatusFound)
		return
	}

}

// handlerEdit handle blog entry edit request
func handlerEdit(w http.ResponseWriter, r *http.Request) {

	validPath := regexp.MustCompile("^/(edit)/([a-zA-Z0-9]+)$")
	m := validPath.FindStringSubmatch(r.URL.Path)
	if len(m) < 2 {
		http.NotFound(w, r)
		return
	}

	id := 0
	var err error
	if id, err = strconv.Atoi(m[2]); err != nil {
		http.NotFound(w, r)
		return
	}

	entry, err := BlogStorage.GetByID(id)
	if isError(err, w) {
		http.NotFound(w, r)
		return

	}

	data := make(map[string]interface{})
	data["PageTitle"] = "Edit"
	data["title"] = entry.Title
	data["body"] = entry.Body
	data["id"] = id
	data["action"] = "edit"
	render(w, "post", data)
}

func main() {

	log.Println("We ready to start")

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		data := make(map[string]interface{})
		data["PageTitle"] = "Workshop blog"
		data["storage"] = BlogStorage.GetAll()
		render(w, "main", data)
	})

	http.HandleFunc("/edit/", handlerEdit)
	http.HandleFunc("/post", handlerPost)

	http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("./img/"))))

	log.Fatal(http.ListenAndServe(":9000", nil))
}
<|endoftext|>


<commit_before>package onecache

import (
	"errors"
	"sync"
)

//AdapterFunc defines the structure of a cache store/backend to be registered
type AdapterFunc func() Store

//Extend registers the given adapter
//Note that if an adapter with the specified name exists, it would be overridden
func Extend(name string, fn AdapterFunc) {
	adapters.add(name, fn)
}

//Get resolves a cache store by name. A non nil error would be returned if the store was found.
func Get(name string) (Store, error) {
	return adapters.get(name)
}

type registeredAdapters struct {
	stores map[string]AdapterFunc
	lock   sync.RWMutex
}

func (r *registeredAdapters) add(name string, fn AdapterFunc) {
	r.lock.Lock()
	r.stores[name] = fn
	r.lock.Unlock()
}

func (r *registeredAdapters) get(name string) (Store, error) {
	r.lock.RLock()
	defer r.lock.RUnlock()

	if fn, ok := r.stores[name]; ok {
		return fn(), nil
	}

	return nil, errors.New("Adapter not found")
}

var adapters *registeredAdapters

func init() {
	adapters = &registeredAdapters{
		stores: make(map[string]AdapterFunc, 10),
	}
}
<commit_msg>Removed defer call since the function has only 2 return paths...<commit_after>package onecache

import (
	"errors"
	"sync"
)

//AdapterFunc defines the structure of a cache store/backend to be registered
type AdapterFunc func() Store

//Extend registers the given adapter
//Note that if an adapter with the specified name exists, it would be overridden
func Extend(name string, fn AdapterFunc) {
	adapters.add(name, fn)
}

//Get resolves a cache store by name. A non nil error would be returned if the store was found.
func Get(name string) (Store, error) {
	return adapters.get(name)
}

type registeredAdapters struct {
	stores map[string]AdapterFunc
	lock   sync.RWMutex
}

func (r *registeredAdapters) add(name string, fn AdapterFunc) {
	r.lock.Lock()
	r.stores[name] = fn
	r.lock.Unlock()
}

func (r *registeredAdapters) get(name string) (Store, error) {
	r.lock.RLock()

	if fn, ok := r.stores[name]; ok {
		r.lock.RUnlock()
		return fn(), nil
	}

	r.lock.RUnlock()
	return nil, errors.New("Adapter not found")
}

var adapters *registeredAdapters

func init() {
	adapters = &registeredAdapters{
		stores: make(map[string]AdapterFunc, 10),
	}
}
<|endoftext|>


<commit_before>package grip

import "github.com/coreos/go-systemd/journal"

func (self *Journaler) SetDefaultLevel(level interface{}) {
	self.defaultLevel = convertPriority(level, self.defaultLevel)
}
func SetDefaultLevel(level interface{}) {
	std.SetDefaultLevel(level)
}

func (self *Journaler) DefaultLevel() journal.Priority {
	return self.defaultLevel
}
func DefaultLevel() journal.Priority {
	return std.defaultLevel
}

func (self *Journaler) SetThreshold(level interface{}) {
	self.thresholdLevel = convertPriority(level, self.thresholdLevel)

}
func SetThreshold(level interface{}) {
	std.SetThreshold(level)
}

func (self *Journaler) GetThresholdLevel() int {
	return int(self.thresholdLevel)
}
func GetThresholdLevel() int {
	return int(std.thresholdLevel)
}

func (self *Journaler) GetThresholdLevelString() string {
	switch {
	case self.thresholdLevel == 0:
		return "emergency"
	case self.thresholdLevel == 1:
		return "alert"
	case self.thresholdLevel == 2:
		return "critical"
	case self.thresholdLevel == 3:
		return "error"
	case self.thresholdLevel == 4:
		return "warning"
	case self.thresholdLevel == 5:
		return "notice"
	case self.thresholdLevel == 6:
		return "info"
	case self.thresholdLevel == 7:
		return "debug"
	default:
		return ""
	}
}
func GetThresholdLevelString() string {
	return std.GetThresholdLevelString()
}

func convertPriority(priority interface{}, fallback journal.Priority) journal.Priority {
	switch p := priority.(type) {
	case string:
		return convertPriorityString(p, fallback)
	case int:
		return convertPriorityInt(p, fallback)
	default:
		return fallback
	}
}

func convertPriorityInt(priority int, fallback journal.Priority) journal.Priority {
	p := fallback

	switch {
	case priority == 0:
		p = journal.PriEmerg
	case priority == 1:
		p = journal.PriAlert
	case priority == 2:
		p = journal.PriCrit
	case priority == 3:
		p = journal.PriErr
	case priority == 4:
		p = journal.PriWarning
	case priority == 5:
		p = journal.PriNotice
	case priority == 6:
		p = journal.PriInfo
	case priority == 7:
		p = journal.PriDebug
	}

	return p
}

func convertPriorityString(priority string, fallback journal.Priority) journal.Priority {
	p := fallback

	switch {
	case priority == "emergency":
		p = journal.PriEmerg
	case priority == "alert":
		p = journal.PriAlert
	case priority == "critical":
		p = journal.PriCrit
	case priority == "error":
		p = journal.PriErr
	case priority == "warning":
		p = journal.PriWarning
	case priority == "notice":
		p = journal.PriNotice
	case priority == "info":
		p = journal.PriInfo
	case priority == "debug":
		p = journal.PriDebug
	}

	return p
}
<commit_msg>refactor priority conversions<commit_after>package grip

import "github.com/coreos/go-systemd/journal"

func (self *Journaler) SetDefaultLevel(level interface{}) {
	self.defaultLevel = convertPriority(level, self.defaultLevel)
}
func SetDefaultLevel(level interface{}) {
	std.SetDefaultLevel(level)
}

func (self *Journaler) DefaultLevel() journal.Priority {
	return self.defaultLevel
}
func DefaultLevel() journal.Priority {
	return std.defaultLevel
}

func (self *Journaler) SetThreshold(level interface{}) {
	self.thresholdLevel = convertPriority(level, self.thresholdLevel)

}
func SetThreshold(level interface{}) {
	std.SetThreshold(level)
}

func (self *Journaler) GetThresholdLevel() int {
	return int(self.thresholdLevel)
}
func GetThresholdLevel() int {
	return int(std.thresholdLevel)
}

func (self *Journaler) GetThresholdLevelString() string {
	return priorityString(convertPriority(self.thresholdLevel, self.defaultLevel))
}

func GetThresholdLevelString() string {
	return std.GetThresholdLevelString()
}

func convertPriority(priority interface{}, fallback journal.Priority) journal.Priority {
	switch p := priority.(type) {
	case string:
		return convertPriorityString(p, fallback)
	case int:
		return convertPriorityInt(p, fallback)
	default:
		return fallback
	}
}

func priorityString(priority journal.Priority) string {
	switch {
	case priority == journal.PriEmerg:
		return "emergency"
	case priority == journal.PriAlert:
		return "alert"
	case priority == journal.PriCrit:
		return "critical"
	case priority == journal.PriErr:
		return "error"
	case priority == journal.PriWarning:
		return "warning"
	case priority == journal.PriNotice:
		return "notice"
	case priority == journal.PriInfo:
		return "info"
	case priority == journal.PriDebug:
		return "debug"
	default:
		return ""
	}
}

func convertPriorityInt(priority int, fallback journal.Priority) journal.Priority {
	switch {
	case priority == 0:
		return journal.PriEmerg
	case priority == 1:
		return journal.PriAlert
	case priority == 2:
		return journal.PriCrit
	case priority == 3:
		return journal.PriErr
	case priority == 4:
		return journal.PriWarning
	case priority == 5:
		return journal.PriNotice
	case priority == 6:
		return journal.PriInfo
	case priority == 7:
		return journal.PriDebug
	default:
		return fallback
	}
}

func convertPriorityString(priority string, fallback journal.Priority) journal.Priority {
	switch {
	case priority == "emergency":
		return journal.PriEmerg
	case priority == "alert":
		return journal.PriAlert
	case priority == "critical":
		return journal.PriCrit
	case priority == "error":
		return journal.PriErr
	case priority == "warning":
		return journal.PriWarning
	case priority == "notice":
		return journal.PriNotice
	case priority == "info":
		return journal.PriInfo
	case priority == "debug":
		return journal.PriDebug
	default:
		return fallback
	}
}
<|endoftext|>


<commit_before>package xmpp

import (
	"fmt"
	"log"
)

// Handles XMPP conversations over a Stream. Use NewClientXMPP and/or
// NewComponentXMPP to create and configuring a XMPP instance.
type XMPP struct {
	// JID associated with the stream. Note: this may be negotiated with the
	// server during setup and so must be used for all messages.
	JID JID
	stream *Stream
	in chan interface{}
	out chan interface{}
	nextFilterId FilterId
	filters map[FilterId]filter
}

func newXMPP(jid JID, stream *Stream) *XMPP {
	x := &XMPP{
		jid,
		stream,
		make(chan interface{}),
		make(chan interface{}),
		0,
		make(map[FilterId]filter),
	}
	go x.sender()
	go x.receiver()
	return x
}

// Send a stanza.
func (x *XMPP) Send(v interface{}) {
	x.out <- v
}

// Return the next stanza.
func (x *XMPP) Recv() (interface{}, error) {
	v := <-x.in
	if e, ok := v.(error); ok {
		return nil, e
	}
	return v, nil
}

func (x *XMPP) SendRecv(iq *Iq) (*Iq, error) {

	fid, ch := x.AddFilter(IqResult(iq.Id))
	defer x.RemoveFilter(fid)

	x.Send(iq)

	stanza := <-ch
	reply, ok := stanza.(*Iq)
	if !ok {
		return nil, fmt.Errorf("Expected Iq, for %T", stanza)
	}
	return reply, nil
}

type FilterId int64

func (fid FilterId) Error() string {
	return fmt.Sprintf("Invalid filter id: %d", fid)
}

func (x *XMPP) AddFilter(fn FilterFn) (FilterId, chan interface{}) {
	ch := make(chan interface{})
	filterId := x.nextFilterId
	x.nextFilterId ++
	x.filters[filterId] = filter{fn, ch}
	return filterId, ch
}

func (x *XMPP) RemoveFilter(id FilterId) error {
	filter, ok := x.filters[id]
	if !ok {
		return id
	}
	close(filter.ch)
	delete(x.filters, id)
	return nil
}

func IqResult(id string) FilterFn {
	return func(v interface{}) bool {
		iq, ok := v.(*Iq)
		if !ok {
			return false
		}
		if iq.Id != id {
			return false
		}
		return true
	}
}

type FilterFn func(v interface{}) bool

type filter struct {
	fn FilterFn
	ch chan interface{}
}

func (x *XMPP) sender() {
	for v := range x.out {
		x.stream.Send(v)
	}
}

func (x *XMPP) receiver() {

	defer close(x.in)

	for {
		start, err := x.stream.Next(nil)
		if err != nil {
			x.in <- err
			return
		}

		var v interface{}
		switch start.Name.Local {
		case "error":
			v = &Error{}
		case "iq":
			v = &Iq{}
		case "message":
			v = &Message{}
		case "presence":
			v = &Presence{}
		default:
			log.Fatal("Unexected element: %T %v", start, start)
		}

		err = x.stream.DecodeElement(v, start)
		if err != nil {
			log.Fatal(err)
		}

		filtered := false
		for _, filter := range x.filters {
			if filter.fn(v) {
				filter.ch <- v
				filtered = true
			}
		}

		if !filtered {
			x.in <- v
		}
	}
}

// BUG(matt): filter id generation is not re-entrant.

// BUG(matt): filters map is not re-entrant.
<commit_msg>Nicer var name to it's clearer it's an error.<commit_after>package xmpp

import (
	"fmt"
	"log"
)

// Handles XMPP conversations over a Stream. Use NewClientXMPP and/or
// NewComponentXMPP to create and configuring a XMPP instance.
type XMPP struct {
	// JID associated with the stream. Note: this may be negotiated with the
	// server during setup and so must be used for all messages.
	JID JID
	stream *Stream
	in chan interface{}
	out chan interface{}
	nextFilterId FilterId
	filters map[FilterId]filter
}

func newXMPP(jid JID, stream *Stream) *XMPP {
	x := &XMPP{
		jid,
		stream,
		make(chan interface{}),
		make(chan interface{}),
		0,
		make(map[FilterId]filter),
	}
	go x.sender()
	go x.receiver()
	return x
}

// Send a stanza.
func (x *XMPP) Send(v interface{}) {
	x.out <- v
}

// Return the next stanza.
func (x *XMPP) Recv() (interface{}, error) {
	v := <-x.in
	if err, ok := v.(error); ok {
		return nil, err
	}
	return v, nil
}

func (x *XMPP) SendRecv(iq *Iq) (*Iq, error) {

	fid, ch := x.AddFilter(IqResult(iq.Id))
	defer x.RemoveFilter(fid)

	x.Send(iq)

	stanza := <-ch
	reply, ok := stanza.(*Iq)
	if !ok {
		return nil, fmt.Errorf("Expected Iq, for %T", stanza)
	}
	return reply, nil
}

type FilterId int64

func (fid FilterId) Error() string {
	return fmt.Sprintf("Invalid filter id: %d", fid)
}

func (x *XMPP) AddFilter(fn FilterFn) (FilterId, chan interface{}) {
	ch := make(chan interface{})
	filterId := x.nextFilterId
	x.nextFilterId ++
	x.filters[filterId] = filter{fn, ch}
	return filterId, ch
}

func (x *XMPP) RemoveFilter(id FilterId) error {
	filter, ok := x.filters[id]
	if !ok {
		return id
	}
	close(filter.ch)
	delete(x.filters, id)
	return nil
}

func IqResult(id string) FilterFn {
	return func(v interface{}) bool {
		iq, ok := v.(*Iq)
		if !ok {
			return false
		}
		if iq.Id != id {
			return false
		}
		return true
	}
}

type FilterFn func(v interface{}) bool

type filter struct {
	fn FilterFn
	ch chan interface{}
}

func (x *XMPP) sender() {
	for v := range x.out {
		x.stream.Send(v)
	}
}

func (x *XMPP) receiver() {

	defer close(x.in)

	for {
		start, err := x.stream.Next(nil)
		if err != nil {
			x.in <- err
			return
		}

		var v interface{}
		switch start.Name.Local {
		case "error":
			v = &Error{}
		case "iq":
			v = &Iq{}
		case "message":
			v = &Message{}
		case "presence":
			v = &Presence{}
		default:
			log.Fatal("Unexected element: %T %v", start, start)
		}

		err = x.stream.DecodeElement(v, start)
		if err != nil {
			log.Fatal(err)
		}

		filtered := false
		for _, filter := range x.filters {
			if filter.fn(v) {
				filter.ch <- v
				filtered = true
			}
		}

		if !filtered {
			x.in <- v
		}
	}
}

// BUG(matt): filter id generation is not re-entrant.

// BUG(matt): filters map is not re-entrant.
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/streadway/amqp"
	"log"
)

type Producer struct {
	connection *amqp.Connection
	channel    *amqp.Channel
	tag        string
	done       chan error
}

func NewProducer(amqpURI, exchange, exchangeType, key, ctag string, reliable bool) (*Producer, error) {
	p := &Producer{
		connection: nil,
		channel:    nil,
		tag:        ctag,
		done:       make(chan error),
	}

	var err error

	log.Printf("Connecting to %s", amqpURI)
	p.connection, err = amqp.Dial(amqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: ", err)
	}

	log.Printf("Getting Channel ")
	p.channel, err = p.connection.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: ", err)
	}

  if len( exchange ) > 0 {
    log.Printf("Declaring Exchange (%s)", exchange)
    if err := p.channel.ExchangeDeclare(
      exchange,     // name
      exchangeType, // type
      true,         // durable
      false,        // auto-deleted
      false,        // internal
      false,        // noWait
      nil,          // arguments
    ); err != nil {
      return nil, fmt.Errorf("Exchange Declare: %s", err)
    }
  }

	// Reliable publisher confirms require confirm.select support from the
	// connection.
	// if reliable {
	// 	if err := p.channel.Confirm(false); err != nil {
	// 		return nil, fmt.Errorf("Channel could not be put into confirm mode: ", err)
	// 	}

	// 	ack, nack := p.channel.NotifyConfirm(make(chan uint64, 1), make(chan uint64, 1))

	// 	// defer confirmOne(ack, nack)
	// }

	return p, nil
}

func (p *Producer) Publish(exchange, routingKey, body string) error {
	log.Printf("Publishing %s (%dB)", body, len(body))

	if err := p.channel.Publish(
		exchange,   // publish to an exchange
		routingKey, // routing to 0 or more queues
		false,      // mandatory
		false,      // immediate
		amqp.Publishing{
			Headers:         amqp.Table{},
			ContentType:     "text/plain",
			ContentEncoding: "",
			Body:            []byte(body),
			DeliveryMode:    amqp.Transient, // 1=non-persistent, 2=persistent
			Priority:        0,              // 0-9
			// a bunch of application/implementation-specific fields
		},
	); err != nil {
		return fmt.Errorf("Exchange Publish: ", err)
	}

	return nil
}

// One would typically keep a channel of publishings, a sequence number, and a
// set of unacknowledged sequence numbers and loop until the publishing channel
// is closed.
func confirmOne(ack, nack chan uint64) {
	log.Printf("waiting for confirmation of one publishing")

	select {
	case tag := <-ack:
		log.Printf("confirmed delivery with delivery tag: %d", tag)
	case tag := <-nack:
		log.Printf("failed delivery of delivery tag: %d", tag)
	}
}
<commit_msg>miserable hack to have persistent messages<commit_after>package main

import (
	"fmt"
	"github.com/streadway/amqp"
	"log"
)

type Producer struct {
	connection *amqp.Connection
	channel    *amqp.Channel
	tag        string
	done       chan error
}

func NewProducer(amqpURI, exchange, exchangeType, key, ctag string, reliable bool) (*Producer, error) {
	p := &Producer{
		connection: nil,
		channel:    nil,
		tag:        ctag,
		done:       make(chan error),
	}

	var err error

	log.Printf("Connecting to %s", amqpURI)
	p.connection, err = amqp.Dial(amqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: ", err)
	}

	log.Printf("Getting Channel ")
	p.channel, err = p.connection.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: ", err)
	}

  if len( exchange ) > 0 {
    log.Printf("Declaring Exchange (%s)", exchange)
    if err := p.channel.ExchangeDeclare(
      exchange,     // name
      exchangeType, // type
      true,         // durable
      false,        // auto-deleted
      false,        // internal
      false,        // noWait
      nil,          // arguments
    ); err != nil {
      return nil, fmt.Errorf("Exchange Declare: %s", err)
    }
  }

	// Reliable publisher confirms require confirm.select support from the
	// connection.
	// if reliable {
	// 	if err := p.channel.Confirm(false); err != nil {
	// 		return nil, fmt.Errorf("Channel could not be put into confirm mode: ", err)
	// 	}

	// 	ack, nack := p.channel.NotifyConfirm(make(chan uint64, 1), make(chan uint64, 1))

	// 	// defer confirmOne(ack, nack)
	// }

	return p, nil
}

func (p *Producer) Publish(exchange, routingKey, body string) error {
	log.Printf("Publishing %s (%dB)", body, len(body))

	if err := p.channel.Publish(
		exchange,   // publish to an exchange
		routingKey, // routing to 0 or more queues
		false,      // mandatory
		false,      // immediate
		amqp.Publishing{
			Headers:         amqp.Table{},
			ContentType:     "text/plain",
			ContentEncoding: "",
			Body:            []byte(body),
			DeliveryMode:    2,               // 1=non-persistent, 2=persistent
			Priority:        0,               // 0-9
			// a bunch of application/implementation-specific fields
		},
	); err != nil {
		return fmt.Errorf("Exchange Publish: ", err)
	}

	return nil
}

// One would typically keep a channel of publishings, a sequence number, and a
// set of unacknowledged sequence numbers and loop until the publishing channel
// is closed.
func confirmOne(ack, nack chan uint64) {
	log.Printf("waiting for confirmation of one publishing")

	select {
	case tag := <-ack:
		log.Printf("confirmed delivery with delivery tag: %d", tag)
	case tag := <-nack:
		log.Printf("failed delivery of delivery tag: %d", tag)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/mattn/go-colorable"
	"github.com/Sirupsen/logrus"
)

func main() {
	logrus.SetOutput(colorable.NewColorableStdout())

	logrus.Info("succeeded")
	logrus.Warn("not correct")
	logrus.Error("something error")
	logrus.Fatal("panic")
}
<commit_msg>gofmt on _example/main.go<commit_after>package main

import (
	"github.com/Sirupsen/logrus"
	"github.com/mattn/go-colorable"
)

func main() {
	logrus.SetOutput(colorable.NewColorableStdout())

	logrus.Info("succeeded")
	logrus.Warn("not correct")
	logrus.Error("something error")
	logrus.Fatal("panic")
}
<|endoftext|>


<commit_before>package mixpanel

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

var exportAPIClient = &http.Client{Timeout: time.Minute}

type ExportClient struct {
	Secret string
	Client *http.Client
}

func NewExportClient(apiSecret string) *ExportClient {
	return &ExportClient{
		Secret: apiSecret,
		Client: exportAPIClient,
	}
}

func (c *ExportClient) get(method string, endpoint string, paramMap map[string]string, dest interface{}) error {
	var (
		err error
		req *http.Request
		r   io.Reader
	)

	if endpoint == "" {
		return fmt.Errorf("endpoint missing")
	}

	endpoint = fmt.Sprintf("https://mixpanel.com/api/2.0/%s", endpoint)

	if paramMap == nil {
		paramMap = map[string]string{}
	}

	params := url.Values{}
	for k, v := range paramMap {
		params[k] = []string{v}
	}

	switch method {
	case "GET":
		enc := params.Encode()
		if enc != "" {
			endpoint = endpoint + "?" + enc
		}
	case "POST":
		r = strings.NewReader(params.Encode())
	default:
		return fmt.Errorf("method not supported: %v", method)
	}

	req, err = http.NewRequest(method, endpoint, r)
	if err != nil {
		return err
	}
	req.SetBasicAuth(c.Secret, "")

	resp, err := c.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	return json.Unmarshal(body, dest)
}

type Profile struct {
	ID         string                 `json:"$distinct_id"`
	Properties map[string]interface{} `json:"$properties"`
}

type ListReponse struct {
	Status     string    `json:"status"`
	Error      string    `json:"error"`
	SessionID  string    `json:"session_id"`
	ComputedAt time.Time `json:"computed_at"`
	Results    []Profile `json:"results"`
	Total      int       `json:"total"`
	Page       int       `json:"page"`
}

type ProfileQuery struct {
	LastSeenAfter    time.Time
	LastSeenBefore   time.Time
	OutputProperties []string
}

func buildQueryString(q *ProfileQuery) (bool, string) {
	parts := []string{}

	if !q.LastSeenBefore.IsZero() {
		parts = append(parts, fmt.Sprintf(`properties["$last_seen"] < datetime(%d)`, q.LastSeenBefore.Unix()))
	}

	if !q.LastSeenAfter.IsZero() {
		parts = append(parts, fmt.Sprintf(`properties["$last_seen"] > datetime(%d)`, q.LastSeenAfter.Unix()))
	}

	if len(parts) == 0 {
		return false, ""
	}

	return true, "(" + strings.Join(parts, " && ") + ")"
}

func mapStr(input []string, mapFunc func(input string) string) []string {
	r := make([]string, len(input))
	for idx, elem := range input {
		r[idx] = mapFunc(elem)
	}
	return r
}

func addQuotes(input string) string {
	return `"` + strings.ReplaceAll(input, `"`, `\"`) + `"`
}

func (c *ExportClient) ListProfiles(q *ProfileQuery) ([]Profile, error) {
	list := []Profile{}
	sessID := ""
	page := 0
	total := 0

	for {
		props := map[string]string{}

		if ok, qStr := buildQueryString(q); ok {
			props["where"] = qStr
		}

		if q.OutputProperties != nil {
			props["output_properties"] = "[" + strings.Join(mapStr(q.OutputProperties, addQuotes), ", ") + "]"
		}

		if sessID != "" && page > 0 {
			props["session_id"] = sessID
			props["page"] = fmt.Sprintf("%d", page)
		}

		r := ListReponse{}
		if err := c.get("GET", "engage", props, &r); err != nil {
			return nil, err
		}

		if r.Error != "" {
			return nil, fmt.Errorf("server error: %s", r.Error)
		}

		list = append(list, r.Results...)

		if r.Total > 0 {
			total = r.Total
		}

		if len(list) >= total {
			break
		}

		sessID = r.SessionID
		page = r.Page + 1
	}

	return list, nil
}

func (c *Client) DeleteProfile(distinctID string) error {
	return c.makeRequestWithData("POST", "engage", Properties{
		"$distinct_id":  distinctID,
		"$token":        c.Token,
		"$ignore_alias": "true",
		"$delete":       "",
	}, sourceScript)
}
<commit_msg>profiles: Make sure this runs on Go <1.12.<commit_after>package mixpanel

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

var exportAPIClient = &http.Client{Timeout: time.Minute}

type ExportClient struct {
	Secret string
	Client *http.Client
}

func NewExportClient(apiSecret string) *ExportClient {
	return &ExportClient{
		Secret: apiSecret,
		Client: exportAPIClient,
	}
}

func (c *ExportClient) get(method string, endpoint string, paramMap map[string]string, dest interface{}) error {
	var (
		err error
		req *http.Request
		r   io.Reader
	)

	if endpoint == "" {
		return fmt.Errorf("endpoint missing")
	}

	endpoint = fmt.Sprintf("https://mixpanel.com/api/2.0/%s", endpoint)

	if paramMap == nil {
		paramMap = map[string]string{}
	}

	params := url.Values{}
	for k, v := range paramMap {
		params[k] = []string{v}
	}

	switch method {
	case "GET":
		enc := params.Encode()
		if enc != "" {
			endpoint = endpoint + "?" + enc
		}
	case "POST":
		r = strings.NewReader(params.Encode())
	default:
		return fmt.Errorf("method not supported: %v", method)
	}

	req, err = http.NewRequest(method, endpoint, r)
	if err != nil {
		return err
	}
	req.SetBasicAuth(c.Secret, "")

	resp, err := c.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	return json.Unmarshal(body, dest)
}

type Profile struct {
	ID         string                 `json:"$distinct_id"`
	Properties map[string]interface{} `json:"$properties"`
}

type ListReponse struct {
	Status     string    `json:"status"`
	Error      string    `json:"error"`
	SessionID  string    `json:"session_id"`
	ComputedAt time.Time `json:"computed_at"`
	Results    []Profile `json:"results"`
	Total      int       `json:"total"`
	Page       int       `json:"page"`
}

type ProfileQuery struct {
	LastSeenAfter    time.Time
	LastSeenBefore   time.Time
	OutputProperties []string
}

func buildQueryString(q *ProfileQuery) (bool, string) {
	parts := []string{}

	if !q.LastSeenBefore.IsZero() {
		parts = append(parts, fmt.Sprintf(`properties["$last_seen"] < datetime(%d)`, q.LastSeenBefore.Unix()))
	}

	if !q.LastSeenAfter.IsZero() {
		parts = append(parts, fmt.Sprintf(`properties["$last_seen"] > datetime(%d)`, q.LastSeenAfter.Unix()))
	}

	if len(parts) == 0 {
		return false, ""
	}

	return true, "(" + strings.Join(parts, " && ") + ")"
}

func mapStr(input []string, mapFunc func(input string) string) []string {
	r := make([]string, len(input))
	for idx, elem := range input {
		r[idx] = mapFunc(elem)
	}
	return r
}

func addQuotes(input string) string {
	return `"` + strings.Replace(input, `"`, `\"`, -1) + `"`
}

func (c *ExportClient) ListProfiles(q *ProfileQuery) ([]Profile, error) {
	list := []Profile{}
	sessID := ""
	page := 0
	total := 0

	for {
		props := map[string]string{}

		if ok, qStr := buildQueryString(q); ok {
			props["where"] = qStr
		}

		if q.OutputProperties != nil {
			props["output_properties"] = "[" + strings.Join(mapStr(q.OutputProperties, addQuotes), ", ") + "]"
		}

		if sessID != "" && page > 0 {
			props["session_id"] = sessID
			props["page"] = fmt.Sprintf("%d", page)
		}

		r := ListReponse{}
		if err := c.get("GET", "engage", props, &r); err != nil {
			return nil, err
		}

		if r.Error != "" {
			return nil, fmt.Errorf("server error: %s", r.Error)
		}

		list = append(list, r.Results...)

		if r.Total > 0 {
			total = r.Total
		}

		if len(list) >= total {
			break
		}

		sessID = r.SessionID
		page = r.Page + 1
	}

	return list, nil
}

func (c *Client) DeleteProfile(distinctID string) error {
	return c.makeRequestWithData("POST", "engage", Properties{
		"$distinct_id":  distinctID,
		"$token":        c.Token,
		"$ignore_alias": "true",
		"$delete":       "",
	}, sourceScript)
}
<|endoftext|>


<commit_before>/*
Copyright 2014 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 versioned_test

import (
	"encoding/json"
	"io"
	"testing"
	"time"

	"k8s.io/api/core/v1"
	apiequality "k8s.io/apimachinery/pkg/api/equality"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	runtimejson "k8s.io/apimachinery/pkg/runtime/serializer/json"
	"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/kubernetes/scheme"
	restclientwatch "k8s.io/client-go/rest/watch"
)

// getDecoder mimics how k8s.io/client-go/rest.createSerializers creates a decoder
func getDecoder() runtime.Decoder {
	jsonSerializer := runtimejson.NewSerializer(runtimejson.DefaultMetaFactory, scheme.Scheme, scheme.Scheme, false)
	directCodecFactory := scheme.Codecs.WithoutConversion()
	return directCodecFactory.DecoderToVersion(jsonSerializer, v1.SchemeGroupVersion)
}

func TestDecoder(t *testing.T) {
	table := []watch.EventType{watch.Added, watch.Deleted, watch.Modified, watch.Error, watch.Bookmark}

	for _, eventType := range table {
		out, in := io.Pipe()

		decoder := restclientwatch.NewDecoder(streaming.NewDecoder(out, getDecoder()), getDecoder())
		expect := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
		encoder := json.NewEncoder(in)
		eType := eventType
		go func() {
			data, err := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), expect)
			if err != nil {
				t.Fatalf("Unexpected error %v", err)
			}
			event := metav1.WatchEvent{
				Type:   string(eType),
				Object: runtime.RawExtension{Raw: json.RawMessage(data)},
			}
			if err := encoder.Encode(&event); err != nil {
				t.Errorf("Unexpected error %v", err)
			}
			in.Close()
		}()

		done := make(chan struct{})
		go func() {
			action, got, err := decoder.Decode()
			if err != nil {
				t.Fatalf("Unexpected error %v", err)
			}
			if e, a := eType, action; e != a {
				t.Errorf("Expected %v, got %v", e, a)
			}
			if e, a := expect, got; !apiequality.Semantic.DeepDerivative(e, a) {
				t.Errorf("Expected %v, got %v", e, a)
			}
			t.Logf("Exited read")
			close(done)
		}()
		<-done

		done = make(chan struct{})
		go func() {
			_, _, err := decoder.Decode()
			if err == nil {
				t.Errorf("Unexpected nil error")
			}
			close(done)
		}()
		<-done

		decoder.Close()
	}
}

func TestDecoder_SourceClose(t *testing.T) {
	out, in := io.Pipe()
	decoder := restclientwatch.NewDecoder(streaming.NewDecoder(out, getDecoder()), getDecoder())

	done := make(chan struct{})

	go func() {
		_, _, err := decoder.Decode()
		if err == nil {
			t.Errorf("Unexpected nil error")
		}
		close(done)
	}()

	in.Close()

	select {
	case <-done:
		break
	case <-time.After(wait.ForeverTestTimeout):
		t.Error("Timeout")
	}
}
<commit_msg>Fix staticcheck in apiserver and client-go pkgs<commit_after>/*
Copyright 2014 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 versioned_test

import (
	"encoding/json"
	"fmt"
	"io"
	"testing"
	"time"

	"k8s.io/api/core/v1"
	apiequality "k8s.io/apimachinery/pkg/api/equality"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	runtimejson "k8s.io/apimachinery/pkg/runtime/serializer/json"
	"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/kubernetes/scheme"
	restclientwatch "k8s.io/client-go/rest/watch"
)

// getDecoder mimics how k8s.io/client-go/rest.createSerializers creates a decoder
func getDecoder() runtime.Decoder {
	jsonSerializer := runtimejson.NewSerializer(runtimejson.DefaultMetaFactory, scheme.Scheme, scheme.Scheme, false)
	directCodecFactory := scheme.Codecs.WithoutConversion()
	return directCodecFactory.DecoderToVersion(jsonSerializer, v1.SchemeGroupVersion)
}

func TestDecoder(t *testing.T) {
	table := []watch.EventType{watch.Added, watch.Deleted, watch.Modified, watch.Error, watch.Bookmark}

	for _, eventType := range table {
		out, in := io.Pipe()

		decoder := restclientwatch.NewDecoder(streaming.NewDecoder(out, getDecoder()), getDecoder())
		expect := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
		encoder := json.NewEncoder(in)
		eType := eventType
		errc := make(chan error)

		go func() {
			data, err := runtime.Encode(scheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), expect)
			if err != nil {
				errc <- fmt.Errorf("Unexpected error %v", err)
				return
			}
			event := metav1.WatchEvent{
				Type:   string(eType),
				Object: runtime.RawExtension{Raw: json.RawMessage(data)},
			}
			if err := encoder.Encode(&event); err != nil {
				t.Errorf("Unexpected error %v", err)
			}
			in.Close()
		}()

		done := make(chan struct{})
		go func() {
			action, got, err := decoder.Decode()
			if err != nil {
				errc <- fmt.Errorf("Unexpected error %v", err)
				return
			}
			if e, a := eType, action; e != a {
				t.Errorf("Expected %v, got %v", e, a)
			}
			if e, a := expect, got; !apiequality.Semantic.DeepDerivative(e, a) {
				t.Errorf("Expected %v, got %v", e, a)
			}
			t.Logf("Exited read")
			close(done)
		}()
		select {
		case err := <-errc:
			t.Fatal(err)
		case <-done:
		}

		done = make(chan struct{})
		go func() {
			_, _, err := decoder.Decode()
			if err == nil {
				t.Errorf("Unexpected nil error")
			}
			close(done)
		}()
		<-done

		decoder.Close()
	}
}

func TestDecoder_SourceClose(t *testing.T) {
	out, in := io.Pipe()
	decoder := restclientwatch.NewDecoder(streaming.NewDecoder(out, getDecoder()), getDecoder())

	done := make(chan struct{})

	go func() {
		_, _, err := decoder.Decode()
		if err == nil {
			t.Errorf("Unexpected nil error")
		}
		close(done)
	}()

	in.Close()

	select {
	case <-done:
		break
	case <-time.After(wait.ForeverTestTimeout):
		t.Error("Timeout")
	}
}
<|endoftext|>


<commit_before>package dataProcess

import (
	"../autils"
	"bytes"
	"database/sql"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

type tStruct struct {
	Name      string `json:"name"`
	Id        string `json:"id"`
	TextAlign string `json:"textAlign"`
}

type tRowsInfo struct {
	Count          int  `json:"count"`
	Core           int  `json:"core"`
	Official       int  `json:"official"`
	Plat           int  `json:"plat"`
	Unuse          int  `json:"unuse"`
	Example_ishtml bool `json:"example_ishtml"`
	DomainCount    int  `json:"domainCount"`
}

type tData struct {
	Columns []tStruct   `json:"columns"`
	Rows    []tRowsInfo `json:"rows"`
}

func TotalData(c *gin.Context, db *sql.DB) {
	tagCh := make(chan []int)
	useTagCh := make(chan []string)
	fullTagCh := make(chan []string)

	go getTagCount(db, tagCh)
	go getUseTag(db, useTagCh)
	go getFullTag(db, fullTagCh)

	counts := <-tagCh
	useTag := <-useTagCh
	fullTag := <-fullTagCh
	row := tRowsInfo{}

	row.Core = counts[0]
	row.Official = counts[1]
	row.Plat = counts[2]
	row.Count = counts[0] + counts[1] + counts[2]

	var unuseTags []string
	for _, v := range fullTag {
		use := false
		for _, val := range useTag {
			if v == val {
				use = true
			}
		}
		if !use {
			unuseTags = append(unuseTags, v)
		}
	}
	row.Unuse = len(unuseTags)

	c.JSON(http.StatusOK, gin.H{
		"status": 0,
		"msg":    "ok",
		"data":   row,
	})
}

func getUseTag(db *sql.DB, ch chan []string) {
	tagCtt := []string{}

	sqlStr := "select distinct tag_name from tags where date_sub(curdate(), INTERVAL ? DAY) <= date(`ana_date`)"

	rows, err := db.Query(sqlStr, 30)
	autils.ErrHadle(err)

	var name string
	for rows.Next() {
		err := rows.Scan(&name)
		autils.ErrHadle(err)
		tagCtt = append(tagCtt, name)
	}
	err = rows.Err()
	autils.ErrHadle(err)

	defer rows.Close()

	ch <- tagCtt
}

func getTagCount(db *sql.DB, ch chan []int) {
	counts := []int{}

	var buf bytes.Buffer
	for i := 1; i < 4; i++ {
		if i != 1 {
			buf.WriteString(" union all ")
		}
		buf.WriteString(" select count(*) from taglist where type =  " + strconv.Itoa(i))
	}
	rows, err := db.Query(buf.String())
	autils.ErrHadle(err)

	var count int
	for rows.Next() {
		err := rows.Scan(&count)
		autils.ErrHadle(err)
		counts = append(counts, count)
	}

	err = rows.Err()
	autils.ErrHadle(err)

	defer rows.Close()

	ch <- counts
}

func getFullTag(db *sql.DB, ch chan []string) {
	tags := []string{}

	rows, err := db.Query("select name from taglist")
	autils.ErrHadle(err)

	var name string
	for rows.Next() {
		err := rows.Scan(&name)
		autils.ErrHadle(err)
		tags = append(tags, name)
	}

	err = rows.Err()
	autils.ErrHadle(err)

	defer rows.Close()

	ch <- tags
}
<commit_msg>update result json struct.<commit_after>package dataProcess

import (
	"../autils"
	"bytes"
	"database/sql"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

type tStruct struct {
	Name      string `json:"name"`
	Id        string `json:"id"`
	//TextAlign string `json:"textAlign"`
}

type tRowsInfo struct {
	Count          int  `json:"count"`
	Core           int  `json:"core"`
	Official       int  `json:"official"`
	Plat           int  `json:"plat"`
	Unuse          int  `json:"unuse"`
	Example_ishtml bool `json:"example_ishtml"`
}

type tData struct {
	Columns []tStruct   `json:"columns"`
	Rows    []tRowsInfo `json:"rows"`
}

func TotalData(c *gin.Context, db *sql.DB) {

	td := tData{}

	tagCh := make(chan []int)
	useTagCh := make(chan []string)
	fullTagCh := make(chan []string)

	go getTagCount(db, tagCh)
	go getUseTag(db, useTagCh)
	go getFullTag(db, fullTagCh)

	counts := <-tagCh
	useTag := <-useTagCh
	fullTag := <-fullTagCh
	row := tRowsInfo{}

	row.Core = counts[0]
	row.Official = counts[1]
	row.Plat = counts[2]
	row.Count = counts[0] + counts[1] + counts[2]

	var unuseTags []string
	for _, v := range fullTag {
		use := false
		for _, val := range useTag {
			if v == val {
				use = true
			}
		}
		if !use {
			unuseTags = append(unuseTags, v)
		}
	}
	row.Unuse = len(unuseTags)

	td.Rows = append(td.Rows, row)

	td.Columns = []tStruct{{
		"组件总量",
		"count",
	},{
		"核心组件数",
		"core",
	},{
		"官方组件数",
		"official",
	},{
		"Plat组件数",
		"plat",
	},{
		"未使用组件数",
		"unuse",
	}}

	c.JSON(http.StatusOK, gin.H{
		"status": 0,
		"msg":    "ok",
		"data":   td,
	})
}

func getUseTag(db *sql.DB, ch chan []string) {
	tagCtt := []string{}

	sqlStr := "select distinct tag_name from tags where date_sub(curdate(), INTERVAL ? DAY) <= date(`ana_date`)"

	rows, err := db.Query(sqlStr, 30)
	autils.ErrHadle(err)

	var name string
	for rows.Next() {
		err := rows.Scan(&name)
		autils.ErrHadle(err)
		tagCtt = append(tagCtt, name)
	}
	err = rows.Err()
	autils.ErrHadle(err)

	defer rows.Close()

	ch <- tagCtt
}

func getTagCount(db *sql.DB, ch chan []int) {
	counts := []int{}

	var buf bytes.Buffer
	for i := 1; i < 4; i++ {
		if i != 1 {
			buf.WriteString(" union all ")
		}
		buf.WriteString(" select count(*) from taglist where type =  " + strconv.Itoa(i))
	}
	rows, err := db.Query(buf.String())
	autils.ErrHadle(err)

	var count int
	for rows.Next() {
		err := rows.Scan(&count)
		autils.ErrHadle(err)
		counts = append(counts, count)
	}

	err = rows.Err()
	autils.ErrHadle(err)

	defer rows.Close()

	ch <- counts
}

func getFullTag(db *sql.DB, ch chan []string) {
	tags := []string{}

	rows, err := db.Query("select name from taglist")
	autils.ErrHadle(err)

	var name string
	for rows.Next() {
		err := rows.Scan(&name)
		autils.ErrHadle(err)
		tags = append(tags, name)
	}

	err = rows.Err()
	autils.ErrHadle(err)

	defer rows.Close()

	ch <- tags
}
<|endoftext|>


<commit_before>package models

import "errors"

var (
	ErrMessageAlreadyInTheChannel = errors.New("message is already in the channel")
	ErrIdIsNotSet                 = errors.New("Id is not set")
	ErrAccountIdIsNotSet          = errors.New("account id is not set")
	ErrOldIdIsNotSet              = errors.New("old id is not set")
	ErrNickIsNotSet               = errors.New("nick is not set")
	ErrGuestsAreNotAllowed        = errors.New("guests are not allowed")

	ErrMessageIdIsNotSet       = errors.New("message id is not set")
	ErrMessageIsNotSet         = errors.New("message is not set")
	ErrParentMessageIsNotSet   = errors.New("parent message is not set")
	ErrParentMessageIdIsNotSet = errors.New("parent message id is not set")
	ErrCreatorIdIsNotSet       = errors.New("creator id is not set")

	ErrChannelIsNotSet                = errors.New("channel is not set")
	ErrChannelIdIsNotSet              = errors.New("channel id is not set")
	ErrChannelContainerIsNotSet       = errors.New("channel container is not set")
	ErCouldntFindAccountIdFromContent = errors.New("couldnt find account id from content")
	ErrAccountIsAlreadyInTheChannel   = errors.New("account is already in the channel")

	ErrChannelParticipantIsNotSet             = errors.New("channel participant is not set")
	ErrCannotAddNewParticipantToPinnedChannel = errors.New("you can not add any participants to pinned activity channel")

	ErrChannelMessageIdIsNotSet = errors.New("channel message id is not set")

	ErrNameIsNotSet       = errors.New("name is not set")
	ErrGroupNameIsNotSet  = errors.New("group name is not set")
	ErrLastSeenAtIsNotSet = errors.New("lastSeenAt is not set")
	ErrAddedAtIsNotSet    = errors.New("addedAt is not set")

	ErrRecipientsNotDefined = errors.New("recipients are not defined")
	ErrCannotOpenChannel    = errors.New("you can not open the channel")
	ErrSlugIsNotSet         = errors.New("slug is not set")

	ErrChannelOrMessageIdIsNotSet = errors.New("channelId/messageId is not set")
)
<commit_msg>Social: add new error<commit_after>package models

import "errors"

var (
	ErrMessageAlreadyInTheChannel = errors.New("message is already in the channel")
	ErrIdIsNotSet                 = errors.New("Id is not set")
	ErrAccountIdIsNotSet          = errors.New("account id is not set")
	ErrOldIdIsNotSet              = errors.New("old id is not set")
	ErrNickIsNotSet               = errors.New("nick is not set")
	ErrGuestsAreNotAllowed        = errors.New("guests are not allowed")

	ErrMessageIdIsNotSet       = errors.New("message id is not set")
	ErrMessageIsNotSet         = errors.New("message is not set")
	ErrParentMessageIsNotSet   = errors.New("parent message is not set")
	ErrParentMessageIdIsNotSet = errors.New("parent message id is not set")
	ErrCreatorIdIsNotSet       = errors.New("creator id is not set")

	ErrChannelIsNotSet                = errors.New("channel is not set")
	ErrChannelIdIsNotSet              = errors.New("channel id is not set")
	ErrChannelContainerIsNotSet       = errors.New("channel container is not set")
	ErCouldntFindAccountIdFromContent = errors.New("couldnt find account id from content")
	ErrAccountIsAlreadyInTheChannel   = errors.New("account is already in the channel")

	ErrChannelParticipantIsNotSet             = errors.New("channel participant is not set")
	ErrCannotAddNewParticipantToPinnedChannel = errors.New("you can not add any participants to pinned activity channel")

	ErrChannelMessageIdIsNotSet = errors.New("channel message id is not set")

	ErrNameIsNotSet       = errors.New("name is not set")
	ErrGroupNameIsNotSet  = errors.New("group name is not set")
	ErrLastSeenAtIsNotSet = errors.New("lastSeenAt is not set")
	ErrAddedAtIsNotSet    = errors.New("addedAt is not set")

	ErrRecipientsNotDefined = errors.New("recipients are not defined")
	ErrCannotOpenChannel    = errors.New("you can not open the channel")
	ErrSlugIsNotSet         = errors.New("slug is not set")

	ErrChannelOrMessageIdIsNotSet = errors.New("channelId/messageId is not set")

	ErrNotLoggedIn = errors.New("not logged in")
)
<|endoftext|>


<commit_before>package loghub

import(
	"time"
	"encoding/json"
	"fmt"
	"log"
)

const (
	ERROR = iota
	WARN
	INFO
	DEBUG
	CREATE
	DELETE
	UPDATE
	QUERY
	RULE_UPDATED
	UPDATE_RULE
	UPDATE_POSITION
	UPDATE_RATE
)

const (
	Reset      = "\x1b[0m"
	Bright     = "\x1b[1m"
	Dim        = "\x1b[2m"
	Underscore = "\x1b[4m"
	Blink      = "\x1b[5m"
	Reverse    = "\x1b[7m"
	Hidden     = "\x1b[8m"

	FgBlack   = "\x1b[30m"
	FgRed     = "\x1b[31m"
	FgGreen   = "\x1b[32m"
	FgYellow  = "\x1b[33m"
	FgBlue    = "\x1b[34m"
	FgMagenta = "\x1b[35m"
	FgCyan    = "\x1b[36m"
	FgWhite   = "\x1b[37m"

	BgBlack   = "\x1b[40m"
	BgRed     = "\x1b[41m"
	BgGreen   = "\x1b[42m"
	BgYellow  = "\x1b[43m"
	BgBlue    = "\x1b[44m"
	BgMagenta = "\x1b[45m"
	BgCyan    = "\x1b[46m"
	BgWhite   = "\x1b[47m"
)

var LogInfo = map[int]string{
	0: "ERROR",
	1: "WARN",
	2: "INFO",
	3: "DEBUG",
	4: "CREATE",
	5: "DELETE",
	6: "UPDATE",
	7: "QUERY ",
	8: "RULE_UPDATED",
	9: "UPDATE_RULE",
	10: "UPDATE_POSITION",
	11: "UPDATE_RATE",
}

var LogInfoColor = map[int]string{
	0: FgRed + "ERROR" + Reset,
	1: FgYellow + "WARN" + Reset,
	2: FgWhite + "INFO" + Reset,
	3: BgMagenta + "DEBUG" + Reset,
	4: FgCyan + "CREATE" + Reset,
	5: FgCyan + "DELETE" + Reset,
	6: FgCyan + "UPDATE" + Reset,
	7: FgCyan + "QUERY" + Reset,
	8: FgCyan + "UPDATE" + Reset,
}

type LogMsg struct {
	Type int
	Data interface{}
	Id   string
}

var Log chan *LogMsg
var UI chan *LogMsg
var AddLog chan chan []byte
var AddUI chan chan []byte

func Start(){
	Log = make(chan *LogMsg, 10)
	UI = make(chan *LogMsg, 10)
	AddLog = make(chan chan []byte)
	AddUI = make(chan chan []byte)
	go BroadcastStream()
}

// BroadcastStream routes logs and block system changes to websocket hubs
// and terminal.
func BroadcastStream() {
	var batch []interface{}

	var logOut []chan []byte
	var uiOut []chan []byte

	// we batch the logs every 50 ms so we can cut down on the amount
	// of messages we send
	dump := time.NewTicker(50 * time.Millisecond)

	for {
		select {
		case newUI := <- AddUI:
			uiOut = append(uiOut, newUI)
		case newLog := <- AddLog:
			logOut = append(logOut, newLog)
		case <-dump.C:
			if len(batch) == 0 {
				break
			}

			outBatch := struct {
				Log []interface{}
			}{
				batch,
			}

			joutBatch, err := json.Marshal(outBatch)
			if err != nil {
				log.Println("could not broadcast")
			}

			for _, v := range logOut {
				v <- joutBatch
			}

			batch = nil
		case l := <-Log:
			bclog := struct {
				Type string
				Data interface{}
				Id   string
			}{
				LogInfo[l.Type],
				l.Data,
				l.Id,
			}

			fmt.Println(fmt.Sprintf("%s [ %s ][ %s ] %s", time.Now().Format(time.Stamp), l.Id, LogInfoColor[l.Type], l.Data))
			batch = append(batch, bclog)
		case l := <-UI:
			bclog := struct {
				Type string
				Data interface{}
				Id   string
			}{
				LogInfo[l.Type],
				l.Data,
				l.Id,
			}

			j, err := json.Marshal(bclog)
			if err != nil {
				log.Println("could not broadcast")
				break
			}

			for _, v := range uiOut {
				v <- j
			}
		}
	}
}<commit_msg>log messages in json to stdout (console) like we do in the ui<commit_after>package loghub

import (
	"encoding/json"
	"fmt"
	"log"
	"time"
)

const (
	ERROR = iota
	WARN
	INFO
	DEBUG
	CREATE
	DELETE
	UPDATE
	QUERY
	RULE_UPDATED
	UPDATE_RULE
	UPDATE_POSITION
	UPDATE_RATE
)

const (
	Reset      = "\x1b[0m"
	Bright     = "\x1b[1m"
	Dim        = "\x1b[2m"
	Underscore = "\x1b[4m"
	Blink      = "\x1b[5m"
	Reverse    = "\x1b[7m"
	Hidden     = "\x1b[8m"

	FgBlack   = "\x1b[30m"
	FgRed     = "\x1b[31m"
	FgGreen   = "\x1b[32m"
	FgYellow  = "\x1b[33m"
	FgBlue    = "\x1b[34m"
	FgMagenta = "\x1b[35m"
	FgCyan    = "\x1b[36m"
	FgWhite   = "\x1b[37m"

	BgBlack   = "\x1b[40m"
	BgRed     = "\x1b[41m"
	BgGreen   = "\x1b[42m"
	BgYellow  = "\x1b[43m"
	BgBlue    = "\x1b[44m"
	BgMagenta = "\x1b[45m"
	BgCyan    = "\x1b[46m"
	BgWhite   = "\x1b[47m"
)

var LogInfo = map[int]string{
	0:  "ERROR",
	1:  "WARN",
	2:  "INFO",
	3:  "DEBUG",
	4:  "CREATE",
	5:  "DELETE",
	6:  "UPDATE",
	7:  "QUERY ",
	8:  "RULE_UPDATED",
	9:  "UPDATE_RULE",
	10: "UPDATE_POSITION",
	11: "UPDATE_RATE",
}

var LogInfoColor = map[int]string{
	0: FgRed + "ERROR" + Reset,
	1: FgYellow + "WARN" + Reset,
	2: FgWhite + "INFO" + Reset,
	3: BgMagenta + "DEBUG" + Reset,
	4: FgCyan + "CREATE" + Reset,
	5: FgCyan + "DELETE" + Reset,
	6: FgCyan + "UPDATE" + Reset,
	7: FgCyan + "QUERY" + Reset,
	8: FgCyan + "UPDATE" + Reset,
}

type LogMsg struct {
	Type int
	Data interface{}
	Id   string
}

var Log chan *LogMsg
var UI chan *LogMsg
var AddLog chan chan []byte
var AddUI chan chan []byte

func Start() {
	Log = make(chan *LogMsg, 10)
	UI = make(chan *LogMsg, 10)
	AddLog = make(chan chan []byte)
	AddUI = make(chan chan []byte)
	go BroadcastStream()
}

// BroadcastStream routes logs and block system changes to websocket hubs
// and terminal.
func BroadcastStream() {
	var batch []interface{}

	var logOut []chan []byte
	var uiOut []chan []byte

	// we batch the logs every 50 ms so we can cut down on the amount
	// of messages we send
	dump := time.NewTicker(50 * time.Millisecond)

	for {
		select {
		case newUI := <-AddUI:
			uiOut = append(uiOut, newUI)
		case newLog := <-AddLog:
			logOut = append(logOut, newLog)
		case <-dump.C:
			if len(batch) == 0 {
				break
			}

			outBatch := struct {
				Log []interface{}
			}{
				batch,
			}

			joutBatch, err := json.Marshal(outBatch)
			if err != nil {
				log.Println("could not broadcast")
			}

			for _, v := range logOut {
				v <- joutBatch
			}

			batch = nil
		case l := <-Log:
			bclog := struct {
				Type string
				Data interface{}
				Id   string
			}{
				LogInfo[l.Type],
				l.Data,
				l.Id,
			}

			jsonData, err := json.Marshal(l.Data)
			if err != nil {
				log.Println("failed marshaling data into json")
				fmt.Println(fmt.Sprintf("%s [ %s ][ %s ] %s", time.Now().Format(time.Stamp), l.Id, LogInfoColor[l.Type], l.Data))
			} else {
				fmt.Println(fmt.Sprintf("%s [ %s ][ %s ] %s", time.Now().Format(time.Stamp), l.Id, LogInfoColor[l.Type], jsonData))
			}
			batch = append(batch, bclog)
		case l := <-UI:
			bclog := struct {
				Type string
				Data interface{}
				Id   string
			}{
				LogInfo[l.Type],
				l.Data,
				l.Id,
			}

			j, err := json.Marshal(bclog)
			if err != nil {
				log.Println("could not broadcast")
				break
			}

			for _, v := range uiOut {
				v <- j
			}
		}
	}
}
<|endoftext|>