<commit_before>package getput

import (
	"context"
	"errors"
	"log"
	"sync"

	"github.com/anacrolix/dht/v2"
	"github.com/anacrolix/dht/v2/bep44"
	k_nearest_nodes "github.com/anacrolix/dht/v2/k-nearest-nodes"
	"github.com/anacrolix/dht/v2/krpc"
	"github.com/anacrolix/dht/v2/traversal"
)

type PutGetResult struct {
	GetV           interface{}
	GetBytes       []byte
	TraversalStats *traversal.Stats
	SuccessfulPuts []krpc.NodeAddr
}

func Get(
	ctx context.Context, target bep44.Target, s *dht.Server,
) (
	v interface{}, stats *traversal.Stats, err error,
) {
	vChan := make(chan interface{}, 1)
	op := traversal.Start(traversal.OperationInput{
		Alpha:  15,
		Target: target,
		DoQuery: func(ctx context.Context, addr krpc.NodeAddr) traversal.QueryResult {
			res := s.Get(ctx, dht.NewAddr(addr.UDP()), target, 0, dht.QueryRateLimiting{})
			err := res.ToError()
			if err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, dht.TransactionTimeout) {
				//log.Printf("error querying %v: %v", addr, err)
			}
			if r := res.Reply.R; r != nil {
				rv := r.V
				if rv != nil {
					i, err := bep44.NewItem(rv, nil, 0, 0, nil)
					if err != nil {
						log.Printf("re-marshalling v: %v", err)
					}
					h := i.Target()
					if h == target {
						log.Printf("got %v from %v", target, addr)
						select {
						case vChan <- rv:
						default:
						}
					} else {
						log.Printf("returned v failed hash check: %x", h)
					}
				}
			}
			return res.TraversalQueryResult(addr)
		},
		NodeFilter: s.TraversalNodeFilter,
	})
	nodes, err := s.TraversalStartingNodes()
	if err != nil {
		return
	}
	op.AddNodes(nodes)
	select {
	case <-op.Stalled():
		err = errors.New("value not found")
	case v = <-vChan:
	case <-ctx.Done():
		err = ctx.Err()
	}
	op.Stop()
	stats = op.Stats()
	return
}

func Put(
	ctx context.Context, target krpc.ID, s *dht.Server, put interface{},
) (
	stats *traversal.Stats, err error,
) {
	op := traversal.Start(traversal.OperationInput{
		Alpha:  15,
		Target: target,
		DoQuery: func(ctx context.Context, addr krpc.NodeAddr) traversal.QueryResult {
			res := s.Get(ctx, dht.NewAddr(addr.UDP()), target, 0, dht.QueryRateLimiting{})
			err := res.ToError()
			if err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, dht.TransactionTimeout) {
				//log.Printf("error querying %v: %v", addr, err)
			}
			tqr := res.TraversalQueryResult(addr)
			if tqr.ClosestData == nil {
				tqr.ResponseFrom = nil
			}
			return tqr
		},
		NodeFilter: s.TraversalNodeFilter,
	})
	nodes, err := s.TraversalStartingNodes()
	if err != nil {
		return
	}
	op.AddNodes(nodes)
	select {
	case <-op.Stalled():
		if put == nil {
			err = errors.New("value not found")
		}
	case <-ctx.Done():
		err = ctx.Err()
	}
	op.Stop()
	if put != nil {
		item, err := bep44.NewItem(put, nil, 0, 0, nil)
		if err != nil {
			return nil, err
		}
		var wg sync.WaitGroup
		op.Closest().Range(func(elem k_nearest_nodes.Elem) {
			wg.Add(1)
			go func() {
				defer wg.Done()
				res := s.Put(ctx, dht.NewAddr(elem.Addr.UDP()), item, elem.Data.(string), dht.QueryRateLimiting{})
				err := res.ToError()
				if err != nil {
					log.Printf("error putting to %v: %v", elem.Addr, err)
				} else {
					log.Printf("put to %v", elem.Addr)
				}
			}()
		})
		wg.Wait()
	}
	stats = op.Stats()
	return
}
<commit_msg>Fix logging of get target<commit_after>package getput

import (
	"context"
	"errors"
	"log"
	"sync"

	"github.com/anacrolix/dht/v2"
	"github.com/anacrolix/dht/v2/bep44"
	k_nearest_nodes "github.com/anacrolix/dht/v2/k-nearest-nodes"
	"github.com/anacrolix/dht/v2/krpc"
	"github.com/anacrolix/dht/v2/traversal"
)

type PutGetResult struct {
	GetV           interface{}
	GetBytes       []byte
	TraversalStats *traversal.Stats
	SuccessfulPuts []krpc.NodeAddr
}

func Get(
	ctx context.Context, target bep44.Target, s *dht.Server,
) (
	v interface{}, stats *traversal.Stats, err error,
) {
	vChan := make(chan interface{}, 1)
	op := traversal.Start(traversal.OperationInput{
		Alpha:  15,
		Target: target,
		DoQuery: func(ctx context.Context, addr krpc.NodeAddr) traversal.QueryResult {
			res := s.Get(ctx, dht.NewAddr(addr.UDP()), target, 0, dht.QueryRateLimiting{})
			err := res.ToError()
			if err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, dht.TransactionTimeout) {
				//log.Printf("error querying %v: %v", addr, err)
			}
			if r := res.Reply.R; r != nil {
				rv := r.V
				if rv != nil {
					i, err := bep44.NewItem(rv, nil, 0, 0, nil)
					if err != nil {
						log.Printf("re-marshalling v: %v", err)
					}
					h := i.Target()
					if h == target {
						log.Printf("got %x from %v", target, addr)
						select {
						case vChan <- rv:
						default:
						}
					} else {
						log.Printf("returned v failed hash check: %x", h)
					}
				}
			}
			return res.TraversalQueryResult(addr)
		},
		NodeFilter: s.TraversalNodeFilter,
	})
	nodes, err := s.TraversalStartingNodes()
	if err != nil {
		return
	}
	op.AddNodes(nodes)
	select {
	case <-op.Stalled():
		err = errors.New("value not found")
	case v = <-vChan:
	case <-ctx.Done():
		err = ctx.Err()
	}
	op.Stop()
	stats = op.Stats()
	return
}

func Put(
	ctx context.Context, target krpc.ID, s *dht.Server, put interface{},
) (
	stats *traversal.Stats, err error,
) {
	op := traversal.Start(traversal.OperationInput{
		Alpha:  15,
		Target: target,
		DoQuery: func(ctx context.Context, addr krpc.NodeAddr) traversal.QueryResult {
			res := s.Get(ctx, dht.NewAddr(addr.UDP()), target, 0, dht.QueryRateLimiting{})
			err := res.ToError()
			if err != nil && !errors.Is(err, context.Canceled) && !errors.Is(err, dht.TransactionTimeout) {
				//log.Printf("error querying %v: %v", addr, err)
			}
			tqr := res.TraversalQueryResult(addr)
			if tqr.ClosestData == nil {
				tqr.ResponseFrom = nil
			}
			return tqr
		},
		NodeFilter: s.TraversalNodeFilter,
	})
	nodes, err := s.TraversalStartingNodes()
	if err != nil {
		return
	}
	op.AddNodes(nodes)
	select {
	case <-op.Stalled():
		if put == nil {
			err = errors.New("value not found")
		}
	case <-ctx.Done():
		err = ctx.Err()
	}
	op.Stop()
	if put != nil {
		item, err := bep44.NewItem(put, nil, 0, 0, nil)
		if err != nil {
			return nil, err
		}
		var wg sync.WaitGroup
		op.Closest().Range(func(elem k_nearest_nodes.Elem) {
			wg.Add(1)
			go func() {
				defer wg.Done()
				res := s.Put(ctx, dht.NewAddr(elem.Addr.UDP()), item, elem.Data.(string), dht.QueryRateLimiting{})
				err := res.ToError()
				if err != nil {
					log.Printf("error putting to %v: %v", elem.Addr, err)
				} else {
					log.Printf("put to %v", elem.Addr)
				}
			}()
		})
		wg.Wait()
	}
	stats = op.Stats()
	return
}
<|endoftext|>


<commit_before>// +build ignore

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"
)

type DockerInspect struct {
	Id          string
	RepoTags    []string
	RepoDigests []string
}

func sort_u(in []string) []string {
	set := make(map[string]struct{}, len(in))
	for _, item := range in {
		set[item] = struct{}{}
	}
	out := make([]string, 0, len(set))
	for item := range set {
		out = append(out, item)
	}
	sort.Strings(out)
	return out
}

func Main() error {
	// 1. Get the "docker inspect" for all images
	bs, err := exec.Command("docker", "image", "ls", "--filter=dangling=false", "--format={{ .ID }}").Output()
	if err != nil {
		return err
	}
	ids := sort_u(strings.Split(strings.TrimSpace(string(bs)), "\n"))
	bs, err = exec.Command("docker", append([]string{"image", "inspect"}, ids...)...).Output()
	if err != nil {
		return err
	}
	var infos []DockerInspect
	if err := json.Unmarshal(bs, &infos); err != nil {
		return err
	}

	// 2. Decide what to do with each image
	workspacePull := make(map[string]struct{}) // pull these images from remote registries...
	workspaceTag := make(map[string]string)    // ... then tag them with these names
	workspaceLoad := make(map[string]struct{}) // store these images locally with 'docker image save'/'docker image load'

	for _, info := range infos {
		if len(info.RepoDigests) > 0 {
			workspacePull[info.RepoDigests[0]] = struct{}{}
			for _, tag := range info.RepoTags {
				workspaceTag[tag] = info.Id
			}
		} else {
			for _, tag := range info.RepoTags {
				workspaceLoad[tag] = struct{}{}
			}
		}
	}

	// 3. Record and do those things

	// Write the pull/tag steps to a file
	err = func() error {
		var lines []string
		for pull := range workspacePull {
			lines = append(lines, fmt.Sprintf("docker image pull %s\n", pull))
		}
		for tag, id := range workspaceTag {
			lines = append(lines, fmt.Sprintf("docker image tag %s %s\n", id, tag))
		}
		sort.Strings(lines) // NB: relying on "pull" sorting before "tag"

		lines = append([]string{
			"#!/usr/bin/env bash\n",
			"set -x\n",
		}, lines...)

		restoreSh, err := os.OpenFile("docker/images.sh", os.O_CREATE|os.O_WRONLY, 0777)
		if err != nil {
			return err
		}
		defer restoreSh.Close()
		for _, line := range lines {
			if _, err := io.WriteString(restoreSh, line); err != nil {
				return err
			}
		}

		return nil
	}()
	if err != nil {
		return err
	}

	// Run 'docker image save'
	err = func() error {
		localImages := make([]string, 0, len(workspaceLoad))
		for image := range workspaceLoad {
			localImages = append(localImages, image)
		}
		sort.Strings(localImages)

		restoreTar, err := os.OpenFile("docker/images.tar", os.O_CREATE|os.O_WRONLY, 0666)
		if err != nil {
			return err
		}
		defer restoreTar.Close()

		cmd := exec.Command("docker", append([]string{"image", "save"}, localImages...)...)
		cmd.Stdout = restoreTar
		cmd.Stderr = os.Stderr

		if err := cmd.Run(); err != nil {
			return err
		}

		return nil
	}()
	if err != nil {
		return err
	}

	return nil
}

func main() {
	if err := Main(); err != nil {
		fmt.Fprintf(os.Stderr, "%s: error: %v\n", filepath.Base(os.Args[0]), err)
		os.Exit(1)
	}
}
<commit_msg>(from AES) .circleci: amb-images-save-images: Have the "load" step bail if there's an error<commit_after>// +build ignore

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strings"
)

type DockerInspect struct {
	Id          string
	RepoTags    []string
	RepoDigests []string
}

func sort_u(in []string) []string {
	set := make(map[string]struct{}, len(in))
	for _, item := range in {
		set[item] = struct{}{}
	}
	out := make([]string, 0, len(set))
	for item := range set {
		out = append(out, item)
	}
	sort.Strings(out)
	return out
}

func Main() error {
	// 1. Get the "docker inspect" for all images
	bs, err := exec.Command("docker", "image", "ls", "--filter=dangling=false", "--format={{ .ID }}").Output()
	if err != nil {
		return err
	}
	ids := sort_u(strings.Split(strings.TrimSpace(string(bs)), "\n"))
	bs, err = exec.Command("docker", append([]string{"image", "inspect"}, ids...)...).Output()
	if err != nil {
		return err
	}
	var infos []DockerInspect
	if err := json.Unmarshal(bs, &infos); err != nil {
		return err
	}

	// 2. Decide what to do with each image
	workspacePull := make(map[string]struct{}) // pull these images from remote registries...
	workspaceTag := make(map[string]string)    // ... then tag them with these names
	workspaceLoad := make(map[string]struct{}) // store these images locally with 'docker image save'/'docker image load'

	for _, info := range infos {
		if len(info.RepoDigests) > 0 {
			workspacePull[info.RepoDigests[0]] = struct{}{}
			for _, tag := range info.RepoTags {
				workspaceTag[tag] = info.Id
			}
		} else {
			for _, tag := range info.RepoTags {
				workspaceLoad[tag] = struct{}{}
			}
		}
	}

	// 3. Record and do those things

	// Write the pull/tag steps to a file
	err = func() error {
		var lines []string
		for pull := range workspacePull {
			lines = append(lines, fmt.Sprintf("docker image pull %s\n", pull))
		}
		for tag, id := range workspaceTag {
			lines = append(lines, fmt.Sprintf("docker image tag %s %s\n", id, tag))
		}
		sort.Strings(lines) // NB: relying on "pull" sorting before "tag"

		lines = append([]string{
			"#!/usr/bin/env bash\n",
			"set -ex\n",
		}, lines...)

		restoreSh, err := os.OpenFile("docker/images.sh", os.O_CREATE|os.O_WRONLY, 0777)
		if err != nil {
			return err
		}
		defer restoreSh.Close()
		for _, line := range lines {
			if _, err := io.WriteString(restoreSh, line); err != nil {
				return err
			}
		}

		return nil
	}()
	if err != nil {
		return err
	}

	// Run 'docker image save'
	err = func() error {
		localImages := make([]string, 0, len(workspaceLoad))
		for image := range workspaceLoad {
			localImages = append(localImages, image)
		}
		sort.Strings(localImages)

		restoreTar, err := os.OpenFile("docker/images.tar", os.O_CREATE|os.O_WRONLY, 0666)
		if err != nil {
			return err
		}
		defer restoreTar.Close()

		cmd := exec.Command("docker", append([]string{"image", "save"}, localImages...)...)
		cmd.Stdout = restoreTar
		cmd.Stderr = os.Stderr

		if err := cmd.Run(); err != nil {
			return err
		}

		return nil
	}()
	if err != nil {
		return err
	}

	return nil
}

func main() {
	if err := Main(); err != nil {
		fmt.Fprintf(os.Stderr, "%s: error: %v\n", filepath.Base(os.Args[0]), err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package standard

import (
	"api/config"
	"github.com/Sirupsen/logrus"
	"github.com/flosch/pongo2"
	"github.com/inpime/dbox"
	"net/url"
	"store"
	"strings"
	"utils"
)

func (Extension) initTplContext() {
	pongo2.DefaultSet.Globals["NewUUID"] = func() *pongo2.Value {
		return pongo2.AsValue(dbox.NewUUID())
	}

	pongo2.DefaultSet.Globals["Config"] = func() *pongo2.Value {
		return pongo2.AsValue(config.Cfgx.Config(addonName).(Settings).Config)
	}

	pongo2.DefaultSet.Globals["SectionAppConfig"] = func(sectionName *pongo2.Value) *pongo2.Value {
		return pongo2.AsValue(config.Cfgx.Config(sectionName.String()))
	}

	// DeleteFile
	pongo2.DefaultSet.Globals["DeleteFile"] = func(bucketId, fileId *pongo2.Value) *pongo2.Value {
		if !bucketId.IsString() || !fileId.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		return pongo2.AsValue(store.DeleteFileID(bucketId.String(), fileId.String()))
	}

	pongo2.DefaultSet.Globals["NewFile"] = func(bucketName *pongo2.Value) *pongo2.Value {
		if !bucketName.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		file, _ := store.LoadOrNewFileID(bucketName.String(), "")

		return pongo2.AsValue(file)
	}

	// LoadByID load file by ID
	pongo2.DefaultSet.Globals["LoadByID"] = func(
		bucketName,
		fileID *pongo2.Value,
	) *pongo2.Value {

		if !bucketName.IsString() || !fileID.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		file, err := store.LoadOrNewFileID(
			strings.ToLower(bucketName.String()),
			fileID.String())

		if err != nil {
			return pongo2.AsValue(err)
		}

		return pongo2.AsValue(file)
	}

	// Load load file by name
	pongo2.DefaultSet.Globals["Load"] = func(
		bucketName,
		fileName *pongo2.Value,
	) *pongo2.Value {

		if !bucketName.IsString() || !fileName.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		file, _ := store.LoadOrNewFile(
			strings.ToLower(bucketName.String()),
			fileName.String())

		return pongo2.AsValue(file)
	}

	//

	pongo2.DefaultSet.Globals["URLQuery"] = func(args ...*pongo2.Value) *pongo2.Value {
		emptyUrl, _ := url.Parse("")

		if len(args) == 0 {
			return pongo2.AsValue(emptyUrl)
		}

		_url, ok := args[0].Interface().(*url.URL)

		if !ok {
			logrus.WithFields(logrus.Fields{
				"_service": addonName,
			}).Warningf("not expected type %T, want '*url.URL'", args[0].Interface())

			return pongo2.AsValue(emptyUrl)
		}

		if (len(args)-1)%2 != 0 {
			logrus.WithFields(logrus.Fields{
				"_service": addonName,
			}).Warningf("args expected in multiples of two, want %d", len(args)-1)
			return pongo2.AsValue(emptyUrl)
		}

		queryParams := args[1:]
		urlQueryValues := _url.Query()

		for i := 0; i < len(queryParams); i += 2 {
			urlQueryValues.Add(queryParams[i].String(), queryParams[i+1].String())
		}

		_url.RawQuery = urlQueryValues.Encode()

		return pongo2.AsValue(_url)
	}

	// // builds the path part of the URL
	// pongo2.DefaultSet.Globals["URL"] = func(args ...*pongo2.Value) *pongo2.Value {
	// 	emptyUrl, _ := url.Parse("")

	// 	if len(args) == 0 {
	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	routeName := args[0].String()
	// 	route := config.Router.Get(routeName)

	// 	if route == nil {
	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	if (len(args)-1)%2 != 0 {
	// 		logrus.WithFields(logrus.Fields{
	// 			"_service": addonName,
	// 		}).Warningf("args expected in multiples of two, want %d", len(args)-1)
	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	stringArgs := []string{}

	// 	for _, arg := range args[1:] {
	// 		stringArgs = append(stringArgs, arg.String())
	// 	}

	// 	_url, err := route.URLPath(stringArgs...)

	// 	if err != nil {
	// 		logrus.WithError(err).WithFields(logrus.Fields{
	// 			"_service": addonName,
	// 			"args":     stringArgs,
	// 		}).Warning("build url")

	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	return pongo2.AsValue(_url)
	// }

	// Load load file by name
	pongo2.DefaultSet.Globals["M"] = func() *pongo2.Value {

		return pongo2.AsValue(utils.Map())
	}

	pongo2.DefaultSet.Globals["A"] = func() *pongo2.Value {
		return pongo2.AsValue(utils.NewA([]string{}))
	}

	pongo2.DefaultSet.Globals["AIface"] = func() *pongo2.Value {
		return pongo2.AsValue([]interface{}{})
	}

	pongo2.DefaultSet.Globals["Validator"] = func() *pongo2.Value {

		return pongo2.AsValue(NewValidatorData())
	}

	// CreateBucket special function (used only to create a bucket)
	pongo2.DefaultSet.Globals["CreateBucket"] = func(_opt *pongo2.Value) *pongo2.Value {
		opt := utils.Map().LoadFrom(_opt.Interface())

		bucketName := opt.String("Name")
		bucket, err := store.BucketByName(bucketName)

		if opt.Bool("SameAsMetaStoreType") {
			bucket.InitInOneStore(dbox.StoreType(opt.String("MetaDataStoreType")))
		} else {

			bucket.InitMetaDataStore(
				dbox.StoreType(opt.String("MetaDataStoreType")),
				opt.Bool("MetaHaveSuffix")) // store key - <type>.<name>.meta
			bucket.InitMapDataStore(
				dbox.StoreType(opt.String("MapDataStoreType")),
				opt.Bool("MapDataHaveSuffix")) // store key - <type>.<name>.mapdata
			bucket.InitRawDataStore(
				dbox.StoreType(opt.String("RawDataStoreType")),
				opt.Bool("RawDataHaveSuffix")) // store key - <type>.<name>.rawdata
		}

		// Only create new bucket
		if err != dbox.ErrNotFound {
			return pongo2.AsValue(err)
		}

		bucket.MMetaDataFilesMapping().LoadFromM(store.FileMetaMappingDefault)
		bucket.MMapDataFilesMapping().LoadFrom(opt.String("MappingMapDataFiles"))

		if err := bucket.UpdateMapping(); err != nil {
			logrus.WithError(err).Errorf("create new bucket %q: update mapping", bucketName)
			return pongo2.AsValue(err)
		}

		if err := bucket.Sync(); err != nil {
			logrus.WithError(err).Errorf("create new bucket %q: save bucket", bucketName)
			return pongo2.AsValue(err)
		}

		return pongo2.AsValue(bucket)
	}

	pongo2.DefaultSet.Globals["SendEmail"] = func(to, subject, template, context *pongo2.Value) *pongo2.Value {
		trackid, err := SendEmail(to.String(), subject.String(), template.String(), context.Interface())

		if err != nil {
			logrus.WithError(err).
				WithFields(logrus.Fields{
					"_service": addonName,
					"to":       to.String(),
					"subject":  subject.String(),
					"template": template.String(),
					"context":  context.Interface(),
				}).Error("Send email")
			return pongo2.AsValue(err)
		}

		logrus.
			WithFields(logrus.Fields{
				"_service": addonName,
				"to":       to.String(),
				"subject":  subject.String(),
				"template": template.String(),
				"context":  context.Interface(),
				"trackid":  trackid,
			}).Info("Send email")

		return pongo2.AsValue(trackid)
	}
}
<commit_msg>bugfix config<commit_after>package standard

import (
	"api/config"
	"github.com/Sirupsen/logrus"
	"github.com/flosch/pongo2"
	"github.com/inpime/dbox"
	"net/url"
	"store"
	"strings"
	"utils"
)

func (Extension) initTplContext() {
	pongo2.DefaultSet.Globals["NewUUID"] = func() *pongo2.Value {
		return pongo2.AsValue(dbox.NewUUID())
	}

	pongo2.DefaultSet.Globals["Config"] = func() *pongo2.Value {
		return pongo2.AsValue(config.Cfgx.Config(addonName).(*Settings).Config)
	}

	pongo2.DefaultSet.Globals["SectionAppConfig"] = func(sectionName *pongo2.Value) *pongo2.Value {
		return pongo2.AsValue(config.Cfgx.Config(sectionName.String()))
	}

	// DeleteFile
	pongo2.DefaultSet.Globals["DeleteFile"] = func(bucketId, fileId *pongo2.Value) *pongo2.Value {
		if !bucketId.IsString() || !fileId.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		return pongo2.AsValue(store.DeleteFileID(bucketId.String(), fileId.String()))
	}

	pongo2.DefaultSet.Globals["NewFile"] = func(bucketName *pongo2.Value) *pongo2.Value {
		if !bucketName.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		file, _ := store.LoadOrNewFileID(bucketName.String(), "")

		return pongo2.AsValue(file)
	}

	// LoadByID load file by ID
	pongo2.DefaultSet.Globals["LoadByID"] = func(
		bucketName,
		fileID *pongo2.Value,
	) *pongo2.Value {

		if !bucketName.IsString() || !fileID.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		file, err := store.LoadOrNewFileID(
			strings.ToLower(bucketName.String()),
			fileID.String())

		if err != nil {
			return pongo2.AsValue(err)
		}

		return pongo2.AsValue(file)
	}

	// Load load file by name
	pongo2.DefaultSet.Globals["Load"] = func(
		bucketName,
		fileName *pongo2.Value,
	) *pongo2.Value {

		if !bucketName.IsString() || !fileName.IsString() {
			return pongo2.AsValue(ErrNotValidData)
		}

		file, _ := store.LoadOrNewFile(
			strings.ToLower(bucketName.String()),
			fileName.String())

		return pongo2.AsValue(file)
	}

	//

	pongo2.DefaultSet.Globals["URLQuery"] = func(args ...*pongo2.Value) *pongo2.Value {
		emptyUrl, _ := url.Parse("")

		if len(args) == 0 {
			return pongo2.AsValue(emptyUrl)
		}

		_url, ok := args[0].Interface().(*url.URL)

		if !ok {
			logrus.WithFields(logrus.Fields{
				"_service": addonName,
			}).Warningf("not expected type %T, want '*url.URL'", args[0].Interface())

			return pongo2.AsValue(emptyUrl)
		}

		if (len(args)-1)%2 != 0 {
			logrus.WithFields(logrus.Fields{
				"_service": addonName,
			}).Warningf("args expected in multiples of two, want %d", len(args)-1)
			return pongo2.AsValue(emptyUrl)
		}

		queryParams := args[1:]
		urlQueryValues := _url.Query()

		for i := 0; i < len(queryParams); i += 2 {
			urlQueryValues.Add(queryParams[i].String(), queryParams[i+1].String())
		}

		_url.RawQuery = urlQueryValues.Encode()

		return pongo2.AsValue(_url)
	}

	// // builds the path part of the URL
	// pongo2.DefaultSet.Globals["URL"] = func(args ...*pongo2.Value) *pongo2.Value {
	// 	emptyUrl, _ := url.Parse("")

	// 	if len(args) == 0 {
	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	routeName := args[0].String()
	// 	route := config.Router.Get(routeName)

	// 	if route == nil {
	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	if (len(args)-1)%2 != 0 {
	// 		logrus.WithFields(logrus.Fields{
	// 			"_service": addonName,
	// 		}).Warningf("args expected in multiples of two, want %d", len(args)-1)
	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	stringArgs := []string{}

	// 	for _, arg := range args[1:] {
	// 		stringArgs = append(stringArgs, arg.String())
	// 	}

	// 	_url, err := route.URLPath(stringArgs...)

	// 	if err != nil {
	// 		logrus.WithError(err).WithFields(logrus.Fields{
	// 			"_service": addonName,
	// 			"args":     stringArgs,
	// 		}).Warning("build url")

	// 		return pongo2.AsValue(emptyUrl)
	// 	}

	// 	return pongo2.AsValue(_url)
	// }

	// Load load file by name
	pongo2.DefaultSet.Globals["M"] = func() *pongo2.Value {

		return pongo2.AsValue(utils.Map())
	}

	pongo2.DefaultSet.Globals["A"] = func() *pongo2.Value {
		return pongo2.AsValue(utils.NewA([]string{}))
	}

	pongo2.DefaultSet.Globals["AIface"] = func() *pongo2.Value {
		return pongo2.AsValue([]interface{}{})
	}

	pongo2.DefaultSet.Globals["Validator"] = func() *pongo2.Value {

		return pongo2.AsValue(NewValidatorData())
	}

	// CreateBucket special function (used only to create a bucket)
	pongo2.DefaultSet.Globals["CreateBucket"] = func(_opt *pongo2.Value) *pongo2.Value {
		opt := utils.Map().LoadFrom(_opt.Interface())

		bucketName := opt.String("Name")
		bucket, err := store.BucketByName(bucketName)

		if opt.Bool("SameAsMetaStoreType") {
			bucket.InitInOneStore(dbox.StoreType(opt.String("MetaDataStoreType")))
		} else {

			bucket.InitMetaDataStore(
				dbox.StoreType(opt.String("MetaDataStoreType")),
				opt.Bool("MetaHaveSuffix")) // store key - <type>.<name>.meta
			bucket.InitMapDataStore(
				dbox.StoreType(opt.String("MapDataStoreType")),
				opt.Bool("MapDataHaveSuffix")) // store key - <type>.<name>.mapdata
			bucket.InitRawDataStore(
				dbox.StoreType(opt.String("RawDataStoreType")),
				opt.Bool("RawDataHaveSuffix")) // store key - <type>.<name>.rawdata
		}

		// Only create new bucket
		if err != dbox.ErrNotFound {
			return pongo2.AsValue(err)
		}

		bucket.MMetaDataFilesMapping().LoadFromM(store.FileMetaMappingDefault)
		bucket.MMapDataFilesMapping().LoadFrom(opt.String("MappingMapDataFiles"))

		if err := bucket.UpdateMapping(); err != nil {
			logrus.WithError(err).Errorf("create new bucket %q: update mapping", bucketName)
			return pongo2.AsValue(err)
		}

		if err := bucket.Sync(); err != nil {
			logrus.WithError(err).Errorf("create new bucket %q: save bucket", bucketName)
			return pongo2.AsValue(err)
		}

		return pongo2.AsValue(bucket)
	}

	pongo2.DefaultSet.Globals["SendEmail"] = func(to, subject, template, context *pongo2.Value) *pongo2.Value {
		trackid, err := SendEmail(to.String(), subject.String(), template.String(), context.Interface())

		if err != nil {
			logrus.WithError(err).
				WithFields(logrus.Fields{
					"_service": addonName,
					"to":       to.String(),
					"subject":  subject.String(),
					"template": template.String(),
					"context":  context.Interface(),
				}).Error("Send email")
			return pongo2.AsValue(err)
		}

		logrus.
			WithFields(logrus.Fields{
				"_service": addonName,
				"to":       to.String(),
				"subject":  subject.String(),
				"template": template.String(),
				"context":  context.Interface(),
				"trackid":  trackid,
			}).Info("Send email")

		return pongo2.AsValue(trackid)
	}
}
<|endoftext|>


<commit_before>package msi

/*
#include <stdlib.h>
#include "call_microservice.h"
#include "rcMisc.h"
*/
import "C"

import (
	"runtime"
	"unsafe"
)

type Param struct {
	ptr      *C.msParam_t
	rodsType string
}

func NewParam(paramType string) *Param {
	p := new(Param)

	p.rodsType = paramType

	cTypeStr := C.CString(paramType)
	defer C.free(unsafe.Pointer(cTypeStr))

	p.ptr = C.NewParam(cTypeStr)

	runtime.SetFinalizer(p, paramDestructor)

	return p
}

func (param *Param) String() string {

	var cString *C.char

	switch param.rodsType {
	case STR_MS_T:
		cString = (*C.char)(param.ptr.inOutStruct)
	default:
		return (param.rodsType + ".String() not supported")
	}

	return C.GoString(cString)
}

func (param *Param) Bytes() []byte {
	var bytes []byte

	if param.rodsType == BUF_LEN_MS_T {

		internalBuff := param.ptr.inpOutBuf

		outBuff := unsafe.Pointer(internalBuff.buf)

		bufLen := int(internalBuff.len)

		bytes = (*[1 << 30]byte)(outBuff)[:bufLen:bufLen]
	}

	return bytes
}

func (param *Param) SetKVP(data map[string]string) *Param {
	if param.rodsType == KeyValPair_MS_T {
		kvp := (*C.keyValPair_t)(param.ptr.inOutStruct)

		for key, value := range data {
			C.addKeyVal(kvp, C.CString(key), C.CString(value))
		}

	}
	return param
}

func (param *Param) SetInt(val int) *Param {
	if param.rodsType == INT_MS_T {
		*((*C.int)(param.ptr.inOutStruct)) = C.int(val)
	}
	return param
}

func (param *Param) SetString(val string) *Param {
	if param.rodsType == STR_MS_T {
		param.ptr.inOutStruct = unsafe.Pointer(C.CString(val))
	}
	return param
}

func (param *Param) SetDataObjInp(input map[string]interface{}) *Param {
	if param.rodsType == DataObjInp_MS_T {
		var cInput *C.dataObjInp_t = (*C.dataObjInp_t)(param.ptr.inOutStruct)

		cPathByteStr := []byte(input["objPath"].(string))

		for i, c := range cPathByteStr {
			cInput.objPath[i] = C.char(c)
		}

		cInput.objPath[len(cPathByteStr)] = 0

		if _, ok := input["createMode"]; ok {
			cInput.createMode = C.int(input["createMode"].(int))
		}

		if _, ok := input["openFlags"]; ok {
			cInput.openFlags = C.int(input["openFlags"].(int))
		}

	}

	return param
}

func paramDestructor(param *Param) {
	C.FreeMsParam(param.ptr)
}

func ToParam(gParam unsafe.Pointer) *Param {
	param := (*C.msParam_t)(gParam)

	// Go won't let me access param->type directly
	typ := C.GoString(C.GetMSParamType(param))

	return &Param{
		param,
		typ,
	}
}
<commit_msg>Create param.go<commit_after>package msi

/*
#include <stdlib.h>
#include "call_microservice.h"
#include "rcMisc.h"
*/
import "C"

import (
	"runtime"
	"unsafe"
)

// Param is the golang abstraction for *C.msParam_t types
type Param struct {
	ptr      *C.msParam_t
	rodsType string
}

// New param creates a new *Param, with the provided type string
func NewParam(paramType string) *Param {
	p := new(Param)

	p.rodsType = paramType

	cTypeStr := C.CString(paramType)
	defer C.free(unsafe.Pointer(cTypeStr))

	p.ptr = C.NewParam(cTypeStr)

	runtime.SetFinalizer(p, paramDestructor)

	return p
}

// String converts STR_MS_T parameters to golang strings
func (param *Param) String() string {

	var cString *C.char

	switch param.rodsType {
	case STR_MS_T:
		cString = (*C.char)(param.ptr.inOutStruct)
	default:
		return (param.rodsType + ".String() not supported")
	}

	return C.GoString(cString)
}

// Bytes returns the []byte of BUF_LEN_MS_T type parameters
func (param *Param) Bytes() []byte {
	var bytes []byte

	if param.rodsType == BUF_LEN_MS_T {

		internalBuff := param.ptr.inpOutBuf

		outBuff := unsafe.Pointer(internalBuff.buf)

		bufLen := int(internalBuff.len)

		bytes = (*[1 << 30]byte)(outBuff)[:bufLen:bufLen]
	}

	return bytes
}

// SetKVP adds key-value pairs to the underlying KeyValPair_MS_T parameter
func (param *Param) SetKVP(data map[string]string) *Param {
	if param.rodsType == KeyValPair_MS_T {
		kvp := (*C.keyValPair_t)(param.ptr.inOutStruct)

		for key, value := range data {
			C.addKeyVal(kvp, C.CString(key), C.CString(value))
		}

	}
	return param
}

// SetInt sets the integer value of the underlying INT_MS_T parameter
func (param *Param) SetInt(val int) *Param {
	if param.rodsType == INT_MS_T {
		*((*C.int)(param.ptr.inOutStruct)) = C.int(val)
	}
	return param
}

// SetString sets the string value of the underlying STR_MS_T parameter
func (param *Param) SetString(val string) *Param {
	if param.rodsType == STR_MS_T {
		param.ptr.inOutStruct = unsafe.Pointer(C.CString(val))
	}
	return param
}

// SetDataObjInp sets the underlying DataObjInp_MS_T struct fields from a map
// Valid keys and values are: {"objPath": string, "createMode": int, "openFlags": int}
func (param *Param) SetDataObjInp(input map[string]interface{}) *Param {
	if param.rodsType == DataObjInp_MS_T {
		var cInput *C.dataObjInp_t = (*C.dataObjInp_t)(param.ptr.inOutStruct)

		cPathByteStr := []byte(input["objPath"].(string))

		for i, c := range cPathByteStr {
			cInput.objPath[i] = C.char(c)
		}

		cInput.objPath[len(cPathByteStr)] = 0

		if _, ok := input["createMode"]; ok {
			cInput.createMode = C.int(input["createMode"].(int))
		}

		if _, ok := input["openFlags"]; ok {
			cInput.openFlags = C.int(input["openFlags"].(int))
		}

	}

	return param
}

func paramDestructor(param *Param) {
	C.FreeMsParam(param.ptr)
}

// ToParam creates a new *msi.Param from an existing *C.msParam_t
func ToParam(gParam unsafe.Pointer) *Param {
	param := (*C.msParam_t)(gParam)

	// Go won't let me access param->type directly
	typ := C.GoString(C.GetMSParamType(param))

	return &Param{
		param,
		typ,
	}
}
<|endoftext|>


<commit_before>package murmur3

import (
	//"encoding/binary"
	"hash"
	"unsafe"
)

const (
	c1_128 = 0x87c37b91114253d5
	c2_128 = 0x4cf5ad432745937f
)

// Make sure interfaces are correctly implemented.
var (
	_ hash.Hash = new(digest128)
	_ Hash128   = new(digest128)
	_ bmixer    = new(digest128)
)

// Hash128 represents a 128-bit hasher
// Hack: the standard api doesn't define any Hash128 interface.
type Hash128 interface {
	hash.Hash
	Sum128() (uint64, uint64)
}

// digest128 represents a partial evaluation of a 128 bites hash.
type digest128 struct {
	digest
	h1 uint64 // Unfinalized running hash part 1.
	h2 uint64 // Unfinalized running hash part 2.
}

// New128 returns a 128-bit hasher
func New128() Hash128 { return New128WithSeed(0) }

// New128WithSeed returns a 128-bit hasher set with explicit seed value
func New128WithSeed(seed uint32) Hash128 {
	d := new(digest128)
	d.seed = seed
	d.bmixer = d
	d.Reset()
	return d
}

func (d *digest128) Size() int { return 16 }

func (d *digest128) reset() { d.h1, d.h2 = uint64(d.seed), uint64(d.seed) }

func (d *digest128) Sum(b []byte) []byte {
	h1, h2 := d.Sum128()
	return append(b,
		byte(h1>>56), byte(h1>>48), byte(h1>>40), byte(h1>>32),
		byte(h1>>24), byte(h1>>16), byte(h1>>8), byte(h1),

		byte(h2>>56), byte(h2>>48), byte(h2>>40), byte(h2>>32),
		byte(h2>>24), byte(h2>>16), byte(h2>>8), byte(h2),
	)
}

func (d *digest128) bmix(p []byte) (tail []byte) {
	h1, h2 := d.h1, d.h2

	nblocks := len(p) / 16
	for i := 0; i < nblocks; i++ {
		t := (*[2]uint64)(unsafe.Pointer(&p[i*16]))
		k1, k2 := t[0], t[1]

		k1 *= c1_128
		k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31)
		k1 *= c2_128
		h1 ^= k1

		h1 = (h1 << 27) | (h1 >> 37) // rotl64(h1, 27)
		h1 += h2
		h1 = h1*5 + 0x52dce729

		k2 *= c2_128
		k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33)
		k2 *= c1_128
		h2 ^= k2

		h2 = (h2 << 31) | (h2 >> 33) // rotl64(h2, 31)
		h2 += h1
		h2 = h2*5 + 0x38495ab5
	}
	d.h1, d.h2 = h1, h2
	return p[nblocks*d.Size():]
}

func (d *digest128) Sum128() (h1, h2 uint64) {

	h1, h2 = d.h1, d.h2

	var k1, k2 uint64
	switch len(d.tail) & 15 {
	case 15:
		k2 ^= uint64(d.tail[14]) << 48
		fallthrough
	case 14:
		k2 ^= uint64(d.tail[13]) << 40
		fallthrough
	case 13:
		k2 ^= uint64(d.tail[12]) << 32
		fallthrough
	case 12:
		k2 ^= uint64(d.tail[11]) << 24
		fallthrough
	case 11:
		k2 ^= uint64(d.tail[10]) << 16
		fallthrough
	case 10:
		k2 ^= uint64(d.tail[9]) << 8
		fallthrough
	case 9:
		k2 ^= uint64(d.tail[8]) << 0

		k2 *= c2_128
		k2 = (k2 << 33) | (k2 >> 31) // rotl64(k2, 33)
		k2 *= c1_128
		h2 ^= k2

		fallthrough

	case 8:
		k1 ^= uint64(d.tail[7]) << 56
		fallthrough
	case 7:
		k1 ^= uint64(d.tail[6]) << 48
		fallthrough
	case 6:
		k1 ^= uint64(d.tail[5]) << 40
		fallthrough
	case 5:
		k1 ^= uint64(d.tail[4]) << 32
		fallthrough
	case 4:
		k1 ^= uint64(d.tail[3]) << 24
		fallthrough
	case 3:
		k1 ^= uint64(d.tail[2]) << 16
		fallthrough
	case 2:
		k1 ^= uint64(d.tail[1]) << 8
		fallthrough
	case 1:
		k1 ^= uint64(d.tail[0]) << 0
		k1 *= c1_128
		k1 = (k1 << 31) | (k1 >> 33) // rotl64(k1, 31)
		k1 *= c2_128
		h1 ^= k1
	}

	h1 ^= uint64(d.clen)
	h2 ^= uint64(d.clen)

	h1 += h2
	h2 += h1

	h1 = fmix64(h1)
	h2 = fmix64(h2)

	h1 += h2
	h2 += h1

	return h1, h2
}

func fmix64(k uint64) uint64 {
	k ^= k >> 33
	k *= 0xff51afd7ed558ccd
	k ^= k >> 33
	k *= 0xc4ceb9fe1a85ec53
	k ^= k >> 33
	return k
}

/*
func rotl64(x uint64, r byte) uint64 {
	return (x << r) | (x >> (64 - r))
}
*/

// Sum128 returns the MurmurHash3 sum of data. It is equivalent to the
// following sequence (without the extra burden and the extra allocation):
//     hasher := New128()
//     hasher.Write(data)
//     return hasher.Sum128()
func Sum128(data []byte) (h1 uint64, h2 uint64) { return Sum128WithSeed(data, 0) }

// Sum128WithSeed returns the MurmurHash3 sum of data. It is equivalent to the
// following sequence (without the extra burden and the extra allocation):
//     hasher := New128WithSeed(seed)
//     hasher.Write(data)
//     return hasher.Sum128()
func Sum128WithSeed(data []byte, seed uint32) (h1 uint64, h2 uint64) {
	d := &digest128{h1: uint64(seed), h2: uint64(seed)}
	d.seed = seed
	d.tail = d.bmix(data)
	d.clen = len(data)
	return d.Sum128()
}
<commit_msg>Murmur128: use Go 1.9 bits.RotateLeft64 functions (#22)<commit_after>package murmur3

import (
	//"encoding/binary"
	"hash"
	"unsafe"
	"math/bits"
)

const (
	c1_128 = 0x87c37b91114253d5
	c2_128 = 0x4cf5ad432745937f
)

// Make sure interfaces are correctly implemented.
var (
	_ hash.Hash = new(digest128)
	_ Hash128   = new(digest128)
	_ bmixer    = new(digest128)
)

// Hash128 represents a 128-bit hasher
// Hack: the standard api doesn't define any Hash128 interface.
type Hash128 interface {
	hash.Hash
	Sum128() (uint64, uint64)
}

// digest128 represents a partial evaluation of a 128 bites hash.
type digest128 struct {
	digest
	h1 uint64 // Unfinalized running hash part 1.
	h2 uint64 // Unfinalized running hash part 2.
}

// New128 returns a 128-bit hasher
func New128() Hash128 { return New128WithSeed(0) }

// New128WithSeed returns a 128-bit hasher set with explicit seed value
func New128WithSeed(seed uint32) Hash128 {
	d := new(digest128)
	d.seed = seed
	d.bmixer = d
	d.Reset()
	return d
}

func (d *digest128) Size() int { return 16 }

func (d *digest128) reset() { d.h1, d.h2 = uint64(d.seed), uint64(d.seed) }

func (d *digest128) Sum(b []byte) []byte {
	h1, h2 := d.Sum128()
	return append(b,
		byte(h1>>56), byte(h1>>48), byte(h1>>40), byte(h1>>32),
		byte(h1>>24), byte(h1>>16), byte(h1>>8), byte(h1),

		byte(h2>>56), byte(h2>>48), byte(h2>>40), byte(h2>>32),
		byte(h2>>24), byte(h2>>16), byte(h2>>8), byte(h2),
	)
}

func (d *digest128) bmix(p []byte) (tail []byte) {
	h1, h2 := d.h1, d.h2

	nblocks := len(p) / 16
	for i := 0; i < nblocks; i++ {
		t := (*[2]uint64)(unsafe.Pointer(&p[i*16]))
		k1, k2 := t[0], t[1]

		k1 *= c1_128
		k1 = bits.RotateLeft64(k1, 31)
		k1 *= c2_128
		h1 ^= k1

		h1 = bits.RotateLeft64(h1, 27)
		h1 += h2
		h1 = h1*5 + 0x52dce729

		k2 *= c2_128
		k2 = bits.RotateLeft64(k2, 33)
		k2 *= c1_128
		h2 ^= k2

		h2 = bits.RotateLeft64(h2, 31)
		h2 += h1
		h2 = h2*5 + 0x38495ab5
	}
	d.h1, d.h2 = h1, h2
	return p[nblocks*d.Size():]
}

func (d *digest128) Sum128() (h1, h2 uint64) {

	h1, h2 = d.h1, d.h2

	var k1, k2 uint64
	switch len(d.tail) & 15 {
	case 15:
		k2 ^= uint64(d.tail[14]) << 48
		fallthrough
	case 14:
		k2 ^= uint64(d.tail[13]) << 40
		fallthrough
	case 13:
		k2 ^= uint64(d.tail[12]) << 32
		fallthrough
	case 12:
		k2 ^= uint64(d.tail[11]) << 24
		fallthrough
	case 11:
		k2 ^= uint64(d.tail[10]) << 16
		fallthrough
	case 10:
		k2 ^= uint64(d.tail[9]) << 8
		fallthrough
	case 9:
		k2 ^= uint64(d.tail[8]) << 0

		k2 *= c2_128
		k2 = bits.RotateLeft64(k2, 33)
		k2 *= c1_128
		h2 ^= k2

		fallthrough

	case 8:
		k1 ^= uint64(d.tail[7]) << 56
		fallthrough
	case 7:
		k1 ^= uint64(d.tail[6]) << 48
		fallthrough
	case 6:
		k1 ^= uint64(d.tail[5]) << 40
		fallthrough
	case 5:
		k1 ^= uint64(d.tail[4]) << 32
		fallthrough
	case 4:
		k1 ^= uint64(d.tail[3]) << 24
		fallthrough
	case 3:
		k1 ^= uint64(d.tail[2]) << 16
		fallthrough
	case 2:
		k1 ^= uint64(d.tail[1]) << 8
		fallthrough
	case 1:
		k1 ^= uint64(d.tail[0]) << 0
		k1 *= c1_128
		k1 = bits.RotateLeft64(k1, 31)
		k1 *= c2_128
		h1 ^= k1
	}

	h1 ^= uint64(d.clen)
	h2 ^= uint64(d.clen)

	h1 += h2
	h2 += h1

	h1 = fmix64(h1)
	h2 = fmix64(h2)

	h1 += h2
	h2 += h1

	return h1, h2
}

func fmix64(k uint64) uint64 {
	k ^= k >> 33
	k *= 0xff51afd7ed558ccd
	k ^= k >> 33
	k *= 0xc4ceb9fe1a85ec53
	k ^= k >> 33
	return k
}

/*
func rotl64(x uint64, r byte) uint64 {
	return (x << r) | (x >> (64 - r))
}
*/

// Sum128 returns the MurmurHash3 sum of data. It is equivalent to the
// following sequence (without the extra burden and the extra allocation):
//     hasher := New128()
//     hasher.Write(data)
//     return hasher.Sum128()
func Sum128(data []byte) (h1 uint64, h2 uint64) { return Sum128WithSeed(data, 0) }

// Sum128WithSeed returns the MurmurHash3 sum of data. It is equivalent to the
// following sequence (without the extra burden and the extra allocation):
//     hasher := New128WithSeed(seed)
//     hasher.Write(data)
//     return hasher.Sum128()
func Sum128WithSeed(data []byte, seed uint32) (h1 uint64, h2 uint64) {
	d := &digest128{h1: uint64(seed), h2: uint64(seed)}
	d.seed = seed
	d.tail = d.bmix(data)
	d.clen = len(data)
	return d.Sum128()
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/FactomProject/FactomCode/wallet"
	"bytes"
	"fmt"
	"github.com/FactomProject/gocoding"
	"github.com/hoisie/web"
	"github.com/FactomProject/FactomCode/notaryapi"
	"github.com/FactomProject/FactomCode/factomapi"
	"net/url"
	"strconv"
	"encoding/base64"
	"time"

)

var server = web.NewServer()

func serve_init() {

	server.Post(`/v1/submitentry/?`, handleSubmitEntry)
	server.Post(`/v1/submitchain/?`, handleSubmitChain)
	server.Post(`/v1/buycredit/?`, handleBuyCreditPost)
	server.Post(`/v1/creditbalance/?`, handleGetCreditBalancePost)
	server.Post(`/v1/addentry/?`, handleSubmitEntry2)	// Needs to be removed later??

	server.Get(`/v1/creditbalance/?`, handleGetCreditBalancePost)
	server.Get(`/v1/buycredit/?`, handleBuyCreditPost)

	server.Get(`/v1/dblocksbyrange/([^/]+)(?:/([^/]+))?`, handleDBlocksByRange)
	server.Get(`/v1/dblock/([^/]+)(?)`, handleDBlockByHash)
	server.Get(`/v1/eblock/([^/]+)(?)`, handleEBlockByHash)
	server.Get(`/v1/eblockbymr/([^/]+)(?)`, handleEBlockByMR)
	server.Get(`/v1/entry/([^/]+)(?)`, handleEntryByHash)

}

func handleSubmitEntry(ctx *web.Context) {
	// convert a json post to a factom.Entry then submit the entry to factom
	fmt.Fprintln(ctx, "Entry Submitted")

	switch ctx.Params["format"] {
	case "json":
		entry := new (notaryapi.Entry)
		reader := gocoding.ReadBytes([]byte(ctx.Params["entry"]))
		err := factomapi.SafeUnmarshal(reader, entry)
		if  err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
		}

		if err := factomapi.CommitEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
		}

		time.Sleep(1 * time.Second)
		if err := factomapi.RevealEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
		}
		fmt.Fprintln(ctx, "Entry Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

func handleSubmitEntry2(ctx *web.Context) {
	// convert a json post to a factom.Entry then submit the entry to factom
	fmt.Fprintln(ctx, "Entry Submitted")

	switch ctx.Params["format"] {
	case "json":
		j := []byte(ctx.Params["entry"])
		e := new(factomapi.Entry)
		e.UnmarshalJSON(j)
		if err := factomapi.CommitEntry2(e); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err)
		}
		time.Sleep(1 * time.Second)
		if err := factomapi.RevealEntry2(e); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err)
		}
		fmt.Fprintln(ctx, "Entry Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

func handleSubmitChain(ctx *web.Context) {

	// convert a json post to a factomapi.Chain then submit the entry to factomapi
	switch ctx.Params["format"] {
	case "json":
		reader := gocoding.ReadBytes([]byte(ctx.Params["chain"]))
		c := new(notaryapi.EChain)
		factomapi.SafeUnmarshal(reader,c)

		c.GenerateIDFromName()
		if c.FirstEntry == nil {
			fmt.Fprintln(ctx,
				"The first entry is required for submitting the chain:")
			return
		} else {
			c.FirstEntry.ChainID = *c.ChainID
		}

		fmt.Println("c.ChainID:", c.ChainID.String())

		if err := factomapi.CommitChain(c); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
		}

		time.Sleep(1 * time.Second) //?? do we need to queue them up and look for the confirmation

		if err := factomapi.RevealChain(c); err != nil {
			fmt.Println(err.Error())
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
		}

		fmt.Fprintln(ctx, "Chain Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

//func handleEntryPost(ctx *web.Context) {
//	var abortMessage, abortReturn string
//
//	defer func() {
//		if abortMessage != "" && abortReturn != "" {
//			ctx.Header().Add("Location", fmt.Sprint("/failed?message=", abortMessage, "&return=", abortReturn))
//			ctx.WriteHeader(303)
//		} else if abortReturn != "" {
//			ctx.Header().Add("Location", abortReturn)
//			ctx.WriteHeader(303)
//		}
//	}()
//
//	entry := new (notaryapi.Entry)
//	reader := gocoding.ReadBytes([]byte(ctx.Params["entry"]))
//	err := factomapi.SafeUnmarshal(reader, entry)
//
//	err = factomapi.RevealEntry(1, entry)
//
//	if err != nil {
//		abortMessage = fmt.Sprint("An error occured while submitting the entry (entry may have been accepted by the server but was not locally flagged as such): ", err.Error())
//		return
//	}
//
//}
func handleBuyCreditPost(ctx *web.Context) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	var abortMessage, abortReturn string

	defer func() {
		if abortMessage != "" && abortReturn != "" {
			ctx.Header().Add("Location", fmt.Sprint("/failed?message=", abortMessage, "&return=", abortReturn))
			ctx.WriteHeader(303)
		}
	}()

	ecPubKey := new (notaryapi.Hash)
	if ctx.Params["to"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		ecPubKey.Bytes, _ = base64.URLEncoding.DecodeString(ctx.Params["to"])
	}

	fmt.Println("handleBuyCreditPost using pubkey: ", ecPubKey, " requested",ctx.Params["to"])

	factoid, _ := strconv.ParseFloat(ctx.Params["value"], 10)
	value := uint64(factoid*1000000000)
	err := factomapi.BuyEntryCredit(1, ecPubKey, nil, value, 0, nil)

	if err != nil {
		abortMessage = fmt.Sprint("An error occured while submitting the buycredit request: ", err.Error())
		return
	}

	balance, err := factomapi.GetEntryCreditBalance(ecPubKey)

	ecBalance := new(notaryapi.ECBalance)
	ecBalance.Credits = balance
	ecBalance.PublicKey = ecPubKey

	fmt.Println("Balance for pubkey ", ctx.Params["pubkey"], " is: ", balance)

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, ecBalance)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request ")
		return
	}

}
func handleGetCreditBalancePost(ctx *web.Context) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	ecPubKey := new (notaryapi.Hash)
	if ctx.Params["pubkey"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		ecPubKey.Bytes, _ = base64.StdEncoding.DecodeString(ctx.Params["pubkey"])
	}

	fmt.Println("handleGetCreditBalancePost using pubkey: ", ecPubKey, " requested",ctx.Params["pubkey"])

	balance, err := factomapi.GetEntryCreditBalance(ecPubKey)

	ecBalance := new(notaryapi.ECBalance)
	ecBalance.Credits = balance
	ecBalance.PublicKey = ecPubKey

	fmt.Println("Balance for pubkey ", ctx.Params["pubkey"], " is: ", balance)

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, ecBalance)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request ")
		return
	}
}

/*
func handleChainPost(ctx *web.Context) {
	var abortMessage, abortReturn string
	defer func() {
		if abortMessage != "" && abortReturn != "" {
			ctx.Header().Add("Location", fmt.Sprint("/failed?message=", abortMessage, "&return=", abortReturn))
			ctx.WriteHeader(303)
		}
	}()

	fmt.Println("In handlechainPost")
	chain := new (notaryapi.EChain)
	reader := gocoding.ReadBytes([]byte(ctx.Params["chain"]))
	err := factomapi.SafeUnmarshal(reader, chain)

	err = factomapi.RevealChain(1, chain, nil)

	if err != nil {
		abortMessage = fmt.Sprint("An error occured while adding the chain ", err.Error())
		return
	}

}
*/

func handleDBlocksByRange(ctx *web.Context, fromHeightStr string, toHeightStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	fromBlockHeight, err := strconv.Atoi(fromHeightStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad fromBlockHeight")
		return
	}
	toBlockHeight, err := strconv.Atoi(toHeightStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad toBlockHeight")
		return
	}

	dBlocks, err := factomapi.GetDirectoryBloks(uint64(fromBlockHeight), uint64(toBlockHeight))
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlocks)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

}

func handleDBlockByHash(ctx *web.Context, hashStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	dBlock, err := factomapi.GetDirectoryBlokByHashStr(hashStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlock)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request ")
		return
	}

}

func handleEBlockByHash(ctx *web.Context, hashStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	eBlock, err := factomapi.GetEntryBlokByHashStr(hashStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

}
func handleEBlockByMR(ctx *web.Context, mrStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()
	fmt.Println("mrstr:", mrStr)
	newstr,_ := url.QueryUnescape(mrStr)
	fmt.Println("newstr:", newstr)
	eBlock, err := factomapi.GetEntryBlokByMRStr(newstr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

}

func handleEntryByHash(ctx *web.Context, hashStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	entry, err := factomapi.GetEntryByHashStr(hashStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, entry)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}
}
<commit_msg>changed ecoding for pubkey in factomclient<commit_after>package main

import (
	"github.com/FactomProject/FactomCode/wallet"
	"bytes"
	"fmt"
	"github.com/FactomProject/gocoding"
	"github.com/hoisie/web"
	"github.com/FactomProject/FactomCode/notaryapi"
	"github.com/FactomProject/FactomCode/factomapi"
	"net/url"
	"strconv"
	"encoding/hex"
	"time"

)

var server = web.NewServer()

func serve_init() {

	server.Post(`/v1/submitentry/?`, handleSubmitEntry)
	server.Post(`/v1/submitchain/?`, handleSubmitChain)
	server.Post(`/v1/buycredit/?`, handleBuyCreditPost)
	server.Post(`/v1/creditbalance/?`, handleGetCreditBalancePost)
	server.Post(`/v1/addentry/?`, handleSubmitEntry2)	// Needs to be removed later??

	server.Get(`/v1/creditbalance/?`, handleGetCreditBalancePost)
	server.Get(`/v1/buycredit/?`, handleBuyCreditPost)

	server.Get(`/v1/dblocksbyrange/([^/]+)(?:/([^/]+))?`, handleDBlocksByRange)
	server.Get(`/v1/dblock/([^/]+)(?)`, handleDBlockByHash)
	server.Get(`/v1/eblock/([^/]+)(?)`, handleEBlockByHash)
	server.Get(`/v1/eblockbymr/([^/]+)(?)`, handleEBlockByMR)
	server.Get(`/v1/entry/([^/]+)(?)`, handleEntryByHash)

}

func handleSubmitEntry(ctx *web.Context) {
	// convert a json post to a factom.Entry then submit the entry to factom
	fmt.Fprintln(ctx, "Entry Submitted")

	switch ctx.Params["format"] {
	case "json":
		entry := new (notaryapi.Entry)
		reader := gocoding.ReadBytes([]byte(ctx.Params["entry"]))
		err := factomapi.SafeUnmarshal(reader, entry)
		if  err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
		}

		if err := factomapi.CommitEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
		}

		time.Sleep(1 * time.Second)
		if err := factomapi.RevealEntry(entry); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err.Error())
		}
		fmt.Fprintln(ctx, "Entry Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

func handleSubmitEntry2(ctx *web.Context) {
	// convert a json post to a factom.Entry then submit the entry to factom
	fmt.Fprintln(ctx, "Entry Submitted")

	switch ctx.Params["format"] {
	case "json":
		j := []byte(ctx.Params["entry"])
		e := new(factomapi.Entry)
		e.UnmarshalJSON(j)
		if err := factomapi.CommitEntry2(e); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err)
		}
		time.Sleep(1 * time.Second)
		if err := factomapi.RevealEntry2(e); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the entry:", err)
		}
		fmt.Fprintln(ctx, "Entry Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

func handleSubmitChain(ctx *web.Context) {

	// convert a json post to a factomapi.Chain then submit the entry to factomapi
	switch ctx.Params["format"] {
	case "json":
		reader := gocoding.ReadBytes([]byte(ctx.Params["chain"]))
		c := new(notaryapi.EChain)
		factomapi.SafeUnmarshal(reader,c)

		c.GenerateIDFromName()
		if c.FirstEntry == nil {
			fmt.Fprintln(ctx,
				"The first entry is required for submitting the chain:")
			return
		} else {
			c.FirstEntry.ChainID = *c.ChainID
		}

		fmt.Println("c.ChainID:", c.ChainID.String())

		if err := factomapi.CommitChain(c); err != nil {
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
		}

		time.Sleep(1 * time.Second) //?? do we need to queue them up and look for the confirmation

		if err := factomapi.RevealChain(c); err != nil {
			fmt.Println(err.Error())
			fmt.Fprintln(ctx,
				"there was a problem with submitting the chain:", err)
		}

		fmt.Fprintln(ctx, "Chain Submitted")
	default:
		ctx.WriteHeader(403)
	}
}

//func handleEntryPost(ctx *web.Context) {
//	var abortMessage, abortReturn string
//
//	defer func() {
//		if abortMessage != "" && abortReturn != "" {
//			ctx.Header().Add("Location", fmt.Sprint("/failed?message=", abortMessage, "&return=", abortReturn))
//			ctx.WriteHeader(303)
//		} else if abortReturn != "" {
//			ctx.Header().Add("Location", abortReturn)
//			ctx.WriteHeader(303)
//		}
//	}()
//
//	entry := new (notaryapi.Entry)
//	reader := gocoding.ReadBytes([]byte(ctx.Params["entry"]))
//	err := factomapi.SafeUnmarshal(reader, entry)
//
//	err = factomapi.RevealEntry(1, entry)
//
//	if err != nil {
//		abortMessage = fmt.Sprint("An error occured while submitting the entry (entry may have been accepted by the server but was not locally flagged as such): ", err.Error())
//		return
//	}
//
//}
func handleBuyCreditPost(ctx *web.Context) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	var abortMessage, abortReturn string

	defer func() {
		if abortMessage != "" && abortReturn != "" {
			ctx.Header().Add("Location", fmt.Sprint("/failed?message=", abortMessage, "&return=", abortReturn))
			ctx.WriteHeader(303)
		}
	}()

	ecPubKey := new (notaryapi.Hash)
	if ctx.Params["to"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		ecPubKey.Bytes, _ = hex.DecodeString(ctx.Params["to"])
	}

	fmt.Println("handleBuyCreditPost using pubkey: ", ecPubKey, " requested",ctx.Params["to"])

	factoid, _ := strconv.ParseFloat(ctx.Params["value"], 10)
	value := uint64(factoid*1000000000)
	err := factomapi.BuyEntryCredit(1, ecPubKey, nil, value, 0, nil)

	if err != nil {
		abortMessage = fmt.Sprint("An error occured while submitting the buycredit request: ", err.Error())
		return
	}

	balance, err := factomapi.GetEntryCreditBalance(ecPubKey)

	ecBalance := new(notaryapi.ECBalance)
	ecBalance.Credits = balance
	ecBalance.PublicKey = ecPubKey

	fmt.Println("Balance for pubkey ", ctx.Params["pubkey"], " is: ", balance)

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, ecBalance)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request ")
		return
	}

}
func handleGetCreditBalancePost(ctx *web.Context) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	ecPubKey := new (notaryapi.Hash)
	if ctx.Params["pubkey"] == "wallet" {
		ecPubKey.Bytes = (*wallet.ClientPublicKey().Key)[:]
	} else {
		ecPubKey.Bytes, _ = hex.DecodeString(ctx.Params["pubkey"])
	}

	fmt.Println("handleGetCreditBalancePost using pubkey: ", ecPubKey, " requested",ctx.Params["pubkey"])

	balance, err := factomapi.GetEntryCreditBalance(ecPubKey)

	ecBalance := new(notaryapi.ECBalance)
	ecBalance.Credits = balance
	ecBalance.PublicKey = ecPubKey

	fmt.Println("Balance for pubkey ", ctx.Params["pubkey"], " is: ", balance)

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, ecBalance)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request ")
		return
	}
}

/*
func handleChainPost(ctx *web.Context) {
	var abortMessage, abortReturn string
	defer func() {
		if abortMessage != "" && abortReturn != "" {
			ctx.Header().Add("Location", fmt.Sprint("/failed?message=", abortMessage, "&return=", abortReturn))
			ctx.WriteHeader(303)
		}
	}()

	fmt.Println("In handlechainPost")
	chain := new (notaryapi.EChain)
	reader := gocoding.ReadBytes([]byte(ctx.Params["chain"]))
	err := factomapi.SafeUnmarshal(reader, chain)

	err = factomapi.RevealChain(1, chain, nil)

	if err != nil {
		abortMessage = fmt.Sprint("An error occured while adding the chain ", err.Error())
		return
	}

}
*/

func handleDBlocksByRange(ctx *web.Context, fromHeightStr string, toHeightStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	fromBlockHeight, err := strconv.Atoi(fromHeightStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad fromBlockHeight")
		return
	}
	toBlockHeight, err := strconv.Atoi(toHeightStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad toBlockHeight")
		return
	}

	dBlocks, err := factomapi.GetDirectoryBloks(uint64(fromBlockHeight), uint64(toBlockHeight))
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlocks)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

}

func handleDBlockByHash(ctx *web.Context, hashStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	dBlock, err := factomapi.GetDirectoryBlokByHashStr(hashStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, dBlock)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request ")
		return
	}

}

func handleEBlockByHash(ctx *web.Context, hashStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	eBlock, err := factomapi.GetEntryBlokByHashStr(hashStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

}
func handleEBlockByMR(ctx *web.Context, mrStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()
	fmt.Println("mrstr:", mrStr)
	newstr,_ := url.QueryUnescape(mrStr)
	fmt.Println("newstr:", newstr)
	eBlock, err := factomapi.GetEntryBlokByMRStr(newstr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, eBlock)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}

}

func handleEntryByHash(ctx *web.Context, hashStr string) {
	var httpcode int = 200
	buf := new(bytes.Buffer)

	defer func() {
		ctx.WriteHeader(httpcode)
		ctx.Write(buf.Bytes())
	}()

	entry, err := factomapi.GetEntryByHashStr(hashStr)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad Request")
		return
	}

	// Send back JSON response
	err = factomapi.SafeMarshal(buf, entry)
	if err != nil{
		httpcode = 400
		buf.WriteString("Bad request")
		return
	}
}
<|endoftext|>


<commit_before>package flying_test

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"syscall"

	"github.com/concourse/testflight/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
)

var _ = Describe("Flying", func() {
	var tmpdir string
	var fixture, input1, input2 string

	BeforeEach(func() {
		var err error

		tmpdir, err = ioutil.TempDir("", "fly-test")
		Expect(err).NotTo(HaveOccurred())

		fixture = filepath.Join(tmpdir, "fixture")
		input1 = filepath.Join(tmpdir, "input-1")
		input2 = filepath.Join(tmpdir, "input-2")

		err = os.MkdirAll(fixture, 0755)
		Expect(err).NotTo(HaveOccurred())

		err = os.MkdirAll(input1, 0755)
		Expect(err).NotTo(HaveOccurred())

		err = os.MkdirAll(input2, 0755)
		Expect(err).NotTo(HaveOccurred())

		err = ioutil.WriteFile(
			filepath.Join(fixture, "run"),
			[]byte(`#!/bin/sh
echo some output
echo FOO is $FOO
echo ARGS are "$@"
exit 0
`),
			0755,
		)
		Expect(err).NotTo(HaveOccurred())

		err = ioutil.WriteFile(
			filepath.Join(tmpdir, "task.yml"),
			[]byte(`---
platform: linux

image_resource:
  type: docker-image
  source: {repository: busybox}

inputs:
- name: fixture
- name: input-1
- name: input-2

outputs:
- name: output-1
- name: output-2

params:
  FOO: 1

run:
  path: fixture/run
`),
			0644,
		)
		Expect(err).NotTo(HaveOccurred())
	})

	AfterEach(func() {
		os.RemoveAll(tmpdir)
	})

	It("works", func() {
		fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "--", "SOME", "ARGS")
		fly.Dir = tmpdir

		session := helpers.StartFly(fly)

		Eventually(session).Should(gexec.Exit(0))

		Expect(session).To(gbytes.Say("some output"))
		Expect(session).To(gbytes.Say("FOO is 1"))
		Expect(session).To(gbytes.Say("ARGS are SOME ARGS"))
	})

	Describe("hijacking", func() {
		It("executes an interactive command in a running task's container", func() {
			err := ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
mkfifo /tmp/fifo
echo waiting
cat < /tmp/fifo
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())

			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2")
			fly.Dir = tmpdir

			flyS := helpers.StartFly(fly)

			Eventually(flyS).Should(gbytes.Say("executing build"))

			buildRegex := regexp.MustCompile(`executing build (\d+)`)
			matches := buildRegex.FindSubmatch(flyS.Out.Contents())
			buildID := string(matches[1])

			Eventually(flyS).Should(gbytes.Say("waiting"))

			env := exec.Command(flyBin, "-t", targetedConcourse, "hijack", "-b", buildID, "-s", "one-off", "--", "env")
			envS := helpers.StartFly(env)
			<-envS.Exited
			Expect(envS.ExitCode()).To(Equal(0))
			Expect(envS.Out).To(gbytes.Say("FOO=1"))

			hijack := exec.Command(flyBin, "-t", targetedConcourse, "hijack", "-b", buildID, "-s", "one-off", "--", "sh", "-c", "echo marco > /tmp/fifo")
			hijackS := helpers.StartFly(hijack)
			Eventually(flyS).Should(gbytes.Say("marco"))
			Eventually(hijackS).Should(gexec.Exit())
			Eventually(flyS).Should(gexec.Exit(0))
		})
	})

	Describe("uploading inputs with and without -x", func() {
		BeforeEach(func() {
			gitIgnorePath := filepath.Join(input1, ".gitignore")

			err := ioutil.WriteFile(gitIgnorePath, []byte(`*.exist`), 0644)
			Expect(err).NotTo(HaveOccurred())

			fileToBeIgnoredPath := filepath.Join(input1, "expect-not-to.exist")
			err = ioutil.WriteFile(fileToBeIgnoredPath, []byte(`ignored file content`), 0644)
			Expect(err).NotTo(HaveOccurred())

			fileToBeIncludedPath := filepath.Join(input2, "expect-to.exist")
			err = ioutil.WriteFile(fileToBeIncludedPath, []byte(`included file content`), 0644)
			Expect(err).NotTo(HaveOccurred())

			file1 := filepath.Join(input1, "file-1")
			err = ioutil.WriteFile(file1, []byte(`file-1 contents`), 0644)
			Expect(err).NotTo(HaveOccurred())

			file2 := filepath.Join(input2, "file-2")
			err = ioutil.WriteFile(file2, []byte(`file-2 contents`), 0644)
			Expect(err).NotTo(HaveOccurred())

			err = os.Mkdir(filepath.Join(input1, ".git"), 0755)
			Expect(err).NotTo(HaveOccurred())

			err = os.Mkdir(filepath.Join(input1, ".git/refs"), 0755)
			Expect(err).NotTo(HaveOccurred())

			err = os.Mkdir(filepath.Join(input1, ".git/objects"), 0755)
			Expect(err).NotTo(HaveOccurred())

			gitHEADPath := filepath.Join(input1, ".git/HEAD")
			err = ioutil.WriteFile(gitHEADPath, []byte(`ref: refs/heads/master`), 0644)
			Expect(err).NotTo(HaveOccurred())

			err = ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
cp -a input-1/. output-1/
cp -a input-2/. output-2/
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())
		})

		It("uploads git repo input and non git repo input, IGNORING things in the .gitignore for git repo inputs", func() {
			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "-o", "output-1=./output-1", "-o", "output-2=./output-2")
			fly.Dir = tmpdir

			session := helpers.StartFly(fly)
			<-session.Exited

			Expect(session.ExitCode()).To(Equal(0))

			fileToBeIgnoredPath := filepath.Join(tmpdir, "output-1", "expect-not-to.exist")
			fileToBeIncludedPath := filepath.Join(tmpdir, "output-2", "expect-to.exist")
			file1 := filepath.Join(tmpdir, "output-1", "file-1")
			file2 := filepath.Join(tmpdir, "output-2", "file-2")

			_, err := ioutil.ReadFile(fileToBeIgnoredPath)
			Expect(err).To(HaveOccurred())

			Expect(ioutil.ReadFile(fileToBeIncludedPath)).To(Equal([]byte("included file content")))
			Expect(ioutil.ReadFile(file1)).To(Equal([]byte("file-1 contents")))
			Expect(ioutil.ReadFile(file2)).To(Equal([]byte("file-2 contents")))
		})

		It("uploads git repo input and non git repo input, INCLUDING things in the .gitignore for git repo inputs", func() {
			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-x", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "-o", "output-1=./output-1", "-o", "output-2=./output-2")
			fly.Dir = tmpdir

			session := helpers.StartFly(fly)
			<-session.Exited

			Expect(session.ExitCode()).To(Equal(0))

			fileToBeIgnoredPath := filepath.Join(tmpdir, "output-1", "expect-not-to.exist")
			fileToBeIncludedPath := filepath.Join(tmpdir, "output-2", "expect-to.exist")
			file1 := filepath.Join(tmpdir, "output-1", "file-1")
			file2 := filepath.Join(tmpdir, "output-2", "file-2")

			Expect(ioutil.ReadFile(fileToBeIgnoredPath)).To(Equal([]byte("ignored file content")))
			Expect(ioutil.ReadFile(fileToBeIncludedPath)).To(Equal([]byte("included file content")))
			Expect(ioutil.ReadFile(file1)).To(Equal([]byte("file-1 contents")))
			Expect(ioutil.ReadFile(file2)).To(Equal([]byte("file-2 contents")))
		})
	})

	Describe("pulling down outputs", func() {
		It("works", func() {
			err := ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
echo hello > output-1/file-1
echo world > output-2/file-2
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())

			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "-o", "output-1=./output-1", "-o", "output-2=./output-2")
			fly.Dir = tmpdir

			session := helpers.StartFly(fly)
			<-session.Exited

			Expect(session.ExitCode()).To(Equal(0))

			file1 := filepath.Join(tmpdir, "output-1", "file-1")
			file2 := filepath.Join(tmpdir, "output-2", "file-2")

			Expect(ioutil.ReadFile(file1)).To(Equal([]byte("hello\n")))
			Expect(ioutil.ReadFile(file2)).To(Equal([]byte("world\n")))
		})
	})

	Describe("aborting", func() {
		It("terminates the running task", func() {
			err := ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
trap "echo task got sigterm; exit 1" SIGTERM
sleep 1000 &
echo waiting
wait
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())

			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2")
			fly.Dir = tmpdir

			flyS := helpers.StartFly(fly)

			Eventually(flyS).Should(gbytes.Say("waiting"))

			flyS.Signal(syscall.SIGTERM)

			Eventually(flyS).Should(gbytes.Say("task got sigterm"))

			// build should have been aborted
			Eventually(flyS).Should(gexec.Exit(3))
		})
	})
})
<commit_msg>replace -x with --include-ignored<commit_after>package flying_test

import (
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"syscall"

	"github.com/concourse/testflight/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
)

var _ = Describe("Flying", func() {
	var tmpdir string
	var fixture, input1, input2 string

	BeforeEach(func() {
		var err error

		tmpdir, err = ioutil.TempDir("", "fly-test")
		Expect(err).NotTo(HaveOccurred())

		fixture = filepath.Join(tmpdir, "fixture")
		input1 = filepath.Join(tmpdir, "input-1")
		input2 = filepath.Join(tmpdir, "input-2")

		err = os.MkdirAll(fixture, 0755)
		Expect(err).NotTo(HaveOccurred())

		err = os.MkdirAll(input1, 0755)
		Expect(err).NotTo(HaveOccurred())

		err = os.MkdirAll(input2, 0755)
		Expect(err).NotTo(HaveOccurred())

		err = ioutil.WriteFile(
			filepath.Join(fixture, "run"),
			[]byte(`#!/bin/sh
echo some output
echo FOO is $FOO
echo ARGS are "$@"
exit 0
`),
			0755,
		)
		Expect(err).NotTo(HaveOccurred())

		err = ioutil.WriteFile(
			filepath.Join(tmpdir, "task.yml"),
			[]byte(`---
platform: linux

image_resource:
  type: docker-image
  source: {repository: busybox}

inputs:
- name: fixture
- name: input-1
- name: input-2

outputs:
- name: output-1
- name: output-2

params:
  FOO: 1

run:
  path: fixture/run
`),
			0644,
		)
		Expect(err).NotTo(HaveOccurred())
	})

	AfterEach(func() {
		os.RemoveAll(tmpdir)
	})

	It("works", func() {
		fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "--", "SOME", "ARGS")
		fly.Dir = tmpdir

		session := helpers.StartFly(fly)

		Eventually(session).Should(gexec.Exit(0))

		Expect(session).To(gbytes.Say("some output"))
		Expect(session).To(gbytes.Say("FOO is 1"))
		Expect(session).To(gbytes.Say("ARGS are SOME ARGS"))
	})

	Describe("hijacking", func() {
		It("executes an interactive command in a running task's container", func() {
			err := ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
mkfifo /tmp/fifo
echo waiting
cat < /tmp/fifo
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())

			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2")
			fly.Dir = tmpdir

			flyS := helpers.StartFly(fly)

			Eventually(flyS).Should(gbytes.Say("executing build"))

			buildRegex := regexp.MustCompile(`executing build (\d+)`)
			matches := buildRegex.FindSubmatch(flyS.Out.Contents())
			buildID := string(matches[1])

			Eventually(flyS).Should(gbytes.Say("waiting"))

			env := exec.Command(flyBin, "-t", targetedConcourse, "hijack", "-b", buildID, "-s", "one-off", "--", "env")
			envS := helpers.StartFly(env)
			<-envS.Exited
			Expect(envS.ExitCode()).To(Equal(0))
			Expect(envS.Out).To(gbytes.Say("FOO=1"))

			hijack := exec.Command(flyBin, "-t", targetedConcourse, "hijack", "-b", buildID, "-s", "one-off", "--", "sh", "-c", "echo marco > /tmp/fifo")
			hijackS := helpers.StartFly(hijack)
			Eventually(flyS).Should(gbytes.Say("marco"))
			Eventually(hijackS).Should(gexec.Exit())
			Eventually(flyS).Should(gexec.Exit(0))
		})
	})

	Describe("uploading inputs with and without --include-ignored", func() {
		BeforeEach(func() {
			gitIgnorePath := filepath.Join(input1, ".gitignore")

			err := ioutil.WriteFile(gitIgnorePath, []byte(`*.exist`), 0644)
			Expect(err).NotTo(HaveOccurred())

			fileToBeIgnoredPath := filepath.Join(input1, "expect-not-to.exist")
			err = ioutil.WriteFile(fileToBeIgnoredPath, []byte(`ignored file content`), 0644)
			Expect(err).NotTo(HaveOccurred())

			fileToBeIncludedPath := filepath.Join(input2, "expect-to.exist")
			err = ioutil.WriteFile(fileToBeIncludedPath, []byte(`included file content`), 0644)
			Expect(err).NotTo(HaveOccurred())

			file1 := filepath.Join(input1, "file-1")
			err = ioutil.WriteFile(file1, []byte(`file-1 contents`), 0644)
			Expect(err).NotTo(HaveOccurred())

			file2 := filepath.Join(input2, "file-2")
			err = ioutil.WriteFile(file2, []byte(`file-2 contents`), 0644)
			Expect(err).NotTo(HaveOccurred())

			err = os.Mkdir(filepath.Join(input1, ".git"), 0755)
			Expect(err).NotTo(HaveOccurred())

			err = os.Mkdir(filepath.Join(input1, ".git/refs"), 0755)
			Expect(err).NotTo(HaveOccurred())

			err = os.Mkdir(filepath.Join(input1, ".git/objects"), 0755)
			Expect(err).NotTo(HaveOccurred())

			gitHEADPath := filepath.Join(input1, ".git/HEAD")
			err = ioutil.WriteFile(gitHEADPath, []byte(`ref: refs/heads/master`), 0644)
			Expect(err).NotTo(HaveOccurred())

			err = ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
cp -a input-1/. output-1/
cp -a input-2/. output-2/
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())
		})

		It("uploads git repo input and non git repo input, IGNORING things in the .gitignore for git repo inputs", func() {
			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "-o", "output-1=./output-1", "-o", "output-2=./output-2")
			fly.Dir = tmpdir

			session := helpers.StartFly(fly)
			<-session.Exited

			Expect(session.ExitCode()).To(Equal(0))

			fileToBeIgnoredPath := filepath.Join(tmpdir, "output-1", "expect-not-to.exist")
			fileToBeIncludedPath := filepath.Join(tmpdir, "output-2", "expect-to.exist")
			file1 := filepath.Join(tmpdir, "output-1", "file-1")
			file2 := filepath.Join(tmpdir, "output-2", "file-2")

			_, err := ioutil.ReadFile(fileToBeIgnoredPath)
			Expect(err).To(HaveOccurred())

			Expect(ioutil.ReadFile(fileToBeIncludedPath)).To(Equal([]byte("included file content")))
			Expect(ioutil.ReadFile(file1)).To(Equal([]byte("file-1 contents")))
			Expect(ioutil.ReadFile(file2)).To(Equal([]byte("file-2 contents")))
		})

		It("uploads git repo input and non git repo input, INCLUDING things in the .gitignore for git repo inputs", func() {
			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "--include-ignored", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "-o", "output-1=./output-1", "-o", "output-2=./output-2")
			fly.Dir = tmpdir

			session := helpers.StartFly(fly)
			<-session.Exited

			Expect(session.ExitCode()).To(Equal(0))

			fileToBeIgnoredPath := filepath.Join(tmpdir, "output-1", "expect-not-to.exist")
			fileToBeIncludedPath := filepath.Join(tmpdir, "output-2", "expect-to.exist")
			file1 := filepath.Join(tmpdir, "output-1", "file-1")
			file2 := filepath.Join(tmpdir, "output-2", "file-2")

			Expect(ioutil.ReadFile(fileToBeIgnoredPath)).To(Equal([]byte("ignored file content")))
			Expect(ioutil.ReadFile(fileToBeIncludedPath)).To(Equal([]byte("included file content")))
			Expect(ioutil.ReadFile(file1)).To(Equal([]byte("file-1 contents")))
			Expect(ioutil.ReadFile(file2)).To(Equal([]byte("file-2 contents")))
		})
	})

	Describe("pulling down outputs", func() {
		It("works", func() {
			err := ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
echo hello > output-1/file-1
echo world > output-2/file-2
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())

			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2", "-o", "output-1=./output-1", "-o", "output-2=./output-2")
			fly.Dir = tmpdir

			session := helpers.StartFly(fly)
			<-session.Exited

			Expect(session.ExitCode()).To(Equal(0))

			file1 := filepath.Join(tmpdir, "output-1", "file-1")
			file2 := filepath.Join(tmpdir, "output-2", "file-2")

			Expect(ioutil.ReadFile(file1)).To(Equal([]byte("hello\n")))
			Expect(ioutil.ReadFile(file2)).To(Equal([]byte("world\n")))
		})
	})

	Describe("aborting", func() {
		It("terminates the running task", func() {
			err := ioutil.WriteFile(
				filepath.Join(fixture, "run"),
				[]byte(`#!/bin/sh
trap "echo task got sigterm; exit 1" SIGTERM
sleep 1000 &
echo waiting
wait
`),
				0755,
			)
			Expect(err).NotTo(HaveOccurred())

			fly := exec.Command(flyBin, "-t", targetedConcourse, "execute", "-c", "task.yml", "-i", "fixture=./fixture", "-i", "input-1=./input-1", "-i", "input-2=./input-2")
			fly.Dir = tmpdir

			flyS := helpers.StartFly(fly)

			Eventually(flyS).Should(gbytes.Say("waiting"))

			flyS.Signal(syscall.SIGTERM)

			Eventually(flyS).Should(gbytes.Say("task got sigterm"))

			// build should have been aborted
			Eventually(flyS).Should(gexec.Exit(3))
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"text/template"
)

type person struct {
	Fname string
	Mname string
	Lname string
	Age   int
}

type persons struct {
	Tenant string
	Data   []person
}

const dtmpl = `
<!DOCTYPE html>

	<meta charset="UTF-8">
	<title>dynamic-templateloop</title>

	Tenant: {{ .Tenant }}

	{{range .Data}}
	Name :{{.Fname}} {{.Mname}}.{{.Lname}}

	Age :{{ .Age }}

	{{end}}

`

func main() {
	p1 := person{"Praveen", "Kumar", "K", 36}
	p2 := person{"Srinivasa", "Reddy", "M", 36}
	p3 := person{"Mahesh", "Reddy", "M", 36}
	data := persons{Tenant: "tenant1", Data: []person{p1, p2, p3}}

	tmpl, err := template.New("dynamic-loop").Parse(dtmpl)
	if err != nil {
		panic(err)
	}

	//var tpl bytes.Buffer
	//tmpl.Execute(&tpl, data)
	//fmt.Println(tpl.String())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		tmpl.Execute(w, persons)
	})
	http.ListenAndServe(":8080", nil)
}
<commit_msg>Update dynamic-template-loop-struct-of-slice-of-struct.go<commit_after>package main

import (
	"net/http"
	"text/template"
)

type person struct {
	Fname string
	Mname string
	Lname string
	Age   int
}

type persons struct {
	Tenant string
	Data   []person
}

const dtmpl = `
<!DOCTYPE html>

	<meta charset="UTF-8">
	<title>dynamic-templateloop</title>

	Tenant: {{ .Tenant }}

	{{range .Data}}
	Name :{{.Fname}} {{.Mname}}.{{.Lname}}

	Age :{{ .Age }}

	{{end}}

`

func main() {
	p1 := person{"Praveen", "Kumar", "K", 36}
	p2 := person{"Srinivasa", "Reddy", "M", 36}
	p3 := person{"Mahesh", "Reddy", "M", 36}
	data := persons{Tenant: "tenant1", Data: []person{p1, p2, p3}}

	tmpl, err := template.New("dynamic-loop").Parse(dtmpl)
	if err != nil {
		panic(err)
	}

	//var tpl bytes.Buffer
	//tmpl.Execute(&tpl, data)
	//fmt.Println(tpl.String())
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		tmpl.Execute(w, data)
	})
	http.ListenAndServe(":8080", nil)
}
<|endoftext|>


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

package dbf

import (
	"github.com/cpmech/gosl/chk"
	"github.com/cpmech/gosl/io"
)

// P holds material parameter names and values
//
// The connected variables to V data holds pointers to other scalars that need to be updated when
// the parameter is changed. For instance, when running simulations with variable parameters.
//
type P struct {

	// input
	N      string  `json:"n"`      // name of parameter
	V      float64 `json:"v"`      // value of parameter
	Min    float64 `json:"min"`    // min value
	Max    float64 `json:"max"`    // max value
	S      float64 `json:"s"`      // standard deviation
	D      string  `json:"d"`      // probability distribution type
	U      string  `json:"u"`      // unit (not verified)
	Adj    int     `json:"adj"`    // adjustable: unique ID (greater than zero)
	Dep    int     `json:"dep"`    // depends on "adj"
	Extra  string  `json:"extra"`  // extra data
	Inact  bool    `json:"inact"`  // parameter is inactive in optimisation
	SetDef bool    `json:"setdef"` // tells model to use a default value

	// auxiliary
	Fcn   T  // a function y=f(t,x)
	Other *P // dependency: connected parameter

	// derived
	conn []*float64 // connected variables to V
}

// Connect connects parameter to variable
func (o *P) Connect(V *float64) {
	o.conn = append(o.conn, V)
	*V = o.V
}

// Set sets parameter, including connected variables
func (o *P) Set(V float64) {
	o.V = V
	for _, v := range o.conn {
		*v = V
	}
}

// Params holds many parameters
//
//   A set of Params can be initialized as follows:
//
//     var params Params
//     params = []*P{
//         {N: "klx", V: 1.0},
//         {N: "kly", V: 2.0},
//         {N: "klz", V: 3.0},
//     }
//
//   Alternatively, see NewParams function
//
type Params []*P

// NewParams returns a set of parameters
//
//   This is an alternative to initializing Params by setting slice items
//
//   A set of Params can be initialized as follows:
//
//     params := NewParams(
//         &P{N: "P1", V: 1},
//         &P{N: "P2", V: 2},
//         &P{N: "P3", V: 3},
//     )
//
//   Alternatively, you may set slice components directly (see Params definition)
//
func NewParams(pp ...interface{}) (o Params) {
	o = make([]*P, len(pp))
	for i, p := range pp {
		o[i] = p.(*P)
	}
	return
}

// Find finds a parameter by name
//  Note: returns nil if not found
func (o *Params) Find(name string) *P {
	for _, p := range *o {
		if p.N == name {
			return p
		}
	}
	return nil
}

// GetValue reads parameter or Panic
// Will panic if name does not exist in parameters set
func (o *Params) GetValue(name string) float64 {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find parameter named %q\n", name)
	}
	return p.V
}

// GetValueOrDefault reads parameter or returns default value
// Will return defaultValue if name does not exist in parameters set
func (o *Params) GetValueOrDefault(name string, defaultValue float64) float64 {
	p := o.Find(name)
	if p == nil {
		return defaultValue
	}
	return p.V
}

// GetBool reads Boolean parameter or Panic
// Returns true if P[name] > 0; otherwise returns false
// Will panic if name does not exist in parameters set
func (o *Params) GetBool(name string) bool {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find Boolean parameter named %q\n", name)
	}
	if p.V > 0 {
		return true
	}
	return false
}

// GetBoolOrDefault reads Boolean parameter or returns default value
// Returns true if P[name] > 0; otherwise returns false
// Will return defaultValue if name does not exist in parameters set
func (o *Params) GetBoolOrDefault(name string, defaultValue bool) bool {
	p := o.Find(name)
	if p == nil {
		return defaultValue
	}
	if p.V > 0 {
		return true
	}
	return false
}

// SetValue sets parameter or Panic
// Will panic if name does not exist in parameters set
func (o *Params) SetValue(name string, value float64) {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find parameter named %q\n", name)
	}
	p.V = value
}

// SetBool sets Boolean parameter or Panic
// Sets +1==true if value > 0; otherwise sets -1==false
// Will panic if name does not exist in parameters set
func (o *Params) SetBool(name string, value float64) {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find Boolean parameter named %q\n", name)
	}
	if value > 0 {
		p.V = +1.0
		return
	}
	p.V = -1.0
}

// CheckLimits check limits of variables given in Min/Max
// Will panic if values are outside corresponding Min/Max range.
func (o *Params) CheckLimits() {
	for _, p := range *o {
		if p.V < p.Min {
			chk.Panic("parameter %q has value smaller than minimum. %v < %v is not aceptable", p.N, p.V, p.Min)
		}
		if p.V > p.Max {
			chk.Panic("parameter %q has value greater than maximum. %v > %v is not aceptable", p.N, p.V, p.Max)
		}
	}
}

// GetValues get parameter values
func (o *Params) GetValues(names []string) (values []float64, found []bool) {
	n := len(names)
	values = make([]float64, n)
	found = make([]bool, n)
	for i, name := range names {
		prm := o.Find(name)
		if prm != nil {
			values[i] = prm.V
			found[i] = true
		}
	}
	return
}

// CheckAndGetValues check min/max limits and return values.
// Will panic if values are outside corresponding min/max range.
// Will also panic if a parameter name is not found.
func (o *Params) CheckAndGetValues(names []string) (values []float64) {
	n := len(names)
	values = make([]float64, n)
	for i, name := range names {
		prm := o.Find(name)
		if prm == nil {
			chk.Panic("cannot find parameter named %q", name)
		}
		if prm.V < prm.Min {
			chk.Panic("parameter %q has value smaller than minimum. %v < %v is not aceptable", name, prm.V, prm.Min)
		}
		if prm.V > prm.Max {
			chk.Panic("parameter %q has value greater than maximum. %v > %v is not aceptable", name, prm.V, prm.Max)
		}
		values[i] = prm.V
	}
	return
}

// CheckAndSetVariables get parameter values and check limits defined in Min and Max
// Will panic if values are outside corresponding Min/Max range.
// Will also panic if a parameter name is not found.
func (o *Params) CheckAndSetVariables(names []string, variables []*float64) {
	n := len(names)
	if len(variables) != n {
		chk.Panic("array of variables must have the same size as the slice of names. %d != %d", len(variables), n)
	}
	for i, name := range names {
		prm := o.Find(name)
		if prm == nil {
			chk.Panic("cannot find parameter named %q", name)
		}
		if prm.V < prm.Min {
			chk.Panic("parameter %q has value smaller than minimum. %v < %v is not aceptable", name, prm.V, prm.Min)
		}
		if prm.V > prm.Max {
			chk.Panic("parameter %q has value greater than maximum. %v > %v is not aceptable", name, prm.V, prm.Max)
		}
		if variables[i] == nil {
			chk.Panic("array of variables must not have nil entries")
		}
		*variables[i] = prm.V
	}
	return
}

// Connect connects parameter
func (o *Params) Connect(V *float64, name, caller string) (errorMessage string) {
	prm := o.Find(name)
	if prm == nil {
		return io.Sf("cannot find parameter named %q as requested by %q\n", name, caller)
	}
	prm.Connect(V)
	return
}

// ConnectSet connects set of parameters
func (o *Params) ConnectSet(V []*float64, names []string, caller string) (errorMessage string) {
	chk.IntAssert(len(V), len(names))
	for i, name := range names {
		prm := o.Find(name)
		io.Pforan("name=%v  prm = %v\n", name, prm)
		if prm == nil {
			errorMessage += io.Sf("cannot find parameter named %q as requested by %q\n", name, caller)
		} else {
			prm.Connect(V[i])
		}
	}
	return
}

// ConnectSetOpt connects set of parameters with some being optional
func (o *Params) ConnectSetOpt(V []*float64, names []string, optional []bool, caller string) (errorMessage string) {
	chk.IntAssert(len(V), len(names))
	chk.IntAssert(len(V), len(optional))
	for i, name := range names {
		prm := o.Find(name)
		if prm == nil {
			if !optional[i] {
				errorMessage += io.Sf("cannot find parameter named %q as requested by %q\n", name, caller)
			}
		} else {
			prm.Connect(V[i])
		}
	}
	return
}

// String returns a summary of parameters
func (o Params) String() (l string) {
	for i, prm := range o {
		if i > 0 {
			l += ",\n"
		}
		l += io.Sf("{")
		l += io.Sf(`"n":%q, `, prm.N)
		l += io.Sf(`"v":%v, `, prm.V)
		l += io.Sf(`"min":%v, `, prm.Min)
		l += io.Sf(`"max":%v, `, prm.Max)
		l += io.Sf(`"s":%v, `, prm.S)
		l += io.Sf(`"d":%q, `, prm.D)
		l += io.Sf(`"u":%q, `, prm.U)
		l += io.Sf(`"adj":%v, `, prm.Adj)
		l += io.Sf(`"dep":%v, `, prm.Dep)
		l += io.Sf(`"extra":%q, `, prm.Extra)
		l += io.Sf(`"inact":%v, `, prm.Inact)
		l += io.Sf(`"setdef":%v`, prm.SetDef)
		l += io.Sf("}")
	}
	return
}
<commit_msg>improve desc of parameters<commit_after>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dbf

import (
	"github.com/cpmech/gosl/chk"
	"github.com/cpmech/gosl/io"
)

// P holds numeric parameters defined by a name N and a value V.
//
// P is convenient to store the range of allowed values in Min and Max,
// and other information such as standard deviation S, probability distribution type D,
// among others.
//
// Dependent variables may be connected to P using Connect so when Set is called,
// the dependendt variable is updated as well.
//
// Other parameters can be linked to this one via the Other data member
// and Fcn may be useful to compute y=f(t,x)
//
type P struct {

	// input
	N      string  `json:"n"`      // name of parameter
	V      float64 `json:"v"`      // value of parameter
	Min    float64 `json:"min"`    // min value
	Max    float64 `json:"max"`    // max value
	S      float64 `json:"s"`      // standard deviation
	D      string  `json:"d"`      // probability distribution type
	U      string  `json:"u"`      // unit (not verified)
	Adj    int     `json:"adj"`    // adjustable: unique ID (greater than zero)
	Dep    int     `json:"dep"`    // depends on "adj"
	Extra  string  `json:"extra"`  // extra data
	Inact  bool    `json:"inact"`  // parameter is inactive in optimisation
	SetDef bool    `json:"setdef"` // tells model to use a default value

	// auxiliary
	Fcn   T  // a function y=f(t,x)
	Other *P // dependency: connected parameter

	// derived
	conn []*float64 // connected variables to V
}

// Connect connects parameter to variable
func (o *P) Connect(V *float64) {
	o.conn = append(o.conn, V)
	*V = o.V
}

// Set sets parameter, including connected variables
func (o *P) Set(V float64) {
	o.V = V
	for _, v := range o.conn {
		*v = V
	}
}

// Params holds many parameters
//
//   A set of Params can be initialized as follows:
//
//     var params Params
//     params = []*P{
//         {N: "klx", V: 1.0},
//         {N: "kly", V: 2.0},
//         {N: "klz", V: 3.0},
//     }
//
//   Alternatively, see NewParams function
//
type Params []*P

// NewParams returns a set of parameters
//
//   This is an alternative to initializing Params by setting slice items
//
//   A set of Params can be initialized as follows:
//
//     params := NewParams(
//         &P{N: "P1", V: 1},
//         &P{N: "P2", V: 2},
//         &P{N: "P3", V: 3},
//     )
//
//   Alternatively, you may set slice components directly (see Params definition)
//
func NewParams(pp ...interface{}) (o Params) {
	o = make([]*P, len(pp))
	for i, p := range pp {
		o[i] = p.(*P)
	}
	return
}

// Find finds a parameter by name
//  Note: returns nil if not found
func (o *Params) Find(name string) *P {
	for _, p := range *o {
		if p.N == name {
			return p
		}
	}
	return nil
}

// GetValue reads parameter or Panic
// Will panic if name does not exist in parameters set
func (o *Params) GetValue(name string) float64 {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find parameter named %q\n", name)
	}
	return p.V
}

// GetValueOrDefault reads parameter or returns default value
// Will return defaultValue if name does not exist in parameters set
func (o *Params) GetValueOrDefault(name string, defaultValue float64) float64 {
	p := o.Find(name)
	if p == nil {
		return defaultValue
	}
	return p.V
}

// GetBool reads Boolean parameter or Panic
// Returns true if P[name] > 0; otherwise returns false
// Will panic if name does not exist in parameters set
func (o *Params) GetBool(name string) bool {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find Boolean parameter named %q\n", name)
	}
	if p.V > 0 {
		return true
	}
	return false
}

// GetBoolOrDefault reads Boolean parameter or returns default value
// Returns true if P[name] > 0; otherwise returns false
// Will return defaultValue if name does not exist in parameters set
func (o *Params) GetBoolOrDefault(name string, defaultValue bool) bool {
	p := o.Find(name)
	if p == nil {
		return defaultValue
	}
	if p.V > 0 {
		return true
	}
	return false
}

// SetValue sets parameter or Panic
// Will panic if name does not exist in parameters set
func (o *Params) SetValue(name string, value float64) {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find parameter named %q\n", name)
	}
	p.V = value
}

// SetBool sets Boolean parameter or Panic
// Sets +1==true if value > 0; otherwise sets -1==false
// Will panic if name does not exist in parameters set
func (o *Params) SetBool(name string, value float64) {
	p := o.Find(name)
	if p == nil {
		chk.Panic("cannot find Boolean parameter named %q\n", name)
	}
	if value > 0 {
		p.V = +1.0
		return
	}
	p.V = -1.0
}

// CheckLimits check limits of variables given in Min/Max
// Will panic if values are outside corresponding Min/Max range.
func (o *Params) CheckLimits() {
	for _, p := range *o {
		if p.V < p.Min {
			chk.Panic("parameter %q has value smaller than minimum. %v < %v is not aceptable", p.N, p.V, p.Min)
		}
		if p.V > p.Max {
			chk.Panic("parameter %q has value greater than maximum. %v > %v is not aceptable", p.N, p.V, p.Max)
		}
	}
}

// GetValues get parameter values
func (o *Params) GetValues(names []string) (values []float64, found []bool) {
	n := len(names)
	values = make([]float64, n)
	found = make([]bool, n)
	for i, name := range names {
		prm := o.Find(name)
		if prm != nil {
			values[i] = prm.V
			found[i] = true
		}
	}
	return
}

// CheckAndGetValues check min/max limits and return values.
// Will panic if values are outside corresponding min/max range.
// Will also panic if a parameter name is not found.
func (o *Params) CheckAndGetValues(names []string) (values []float64) {
	n := len(names)
	values = make([]float64, n)
	for i, name := range names {
		prm := o.Find(name)
		if prm == nil {
			chk.Panic("cannot find parameter named %q", name)
		}
		if prm.V < prm.Min {
			chk.Panic("parameter %q has value smaller than minimum. %v < %v is not aceptable", name, prm.V, prm.Min)
		}
		if prm.V > prm.Max {
			chk.Panic("parameter %q has value greater than maximum. %v > %v is not aceptable", name, prm.V, prm.Max)
		}
		values[i] = prm.V
	}
	return
}

// CheckAndSetVariables get parameter values and check limits defined in Min and Max
// Will panic if values are outside corresponding Min/Max range.
// Will also panic if a parameter name is not found.
func (o *Params) CheckAndSetVariables(names []string, variables []*float64) {
	n := len(names)
	if len(variables) != n {
		chk.Panic("array of variables must have the same size as the slice of names. %d != %d", len(variables), n)
	}
	for i, name := range names {
		prm := o.Find(name)
		if prm == nil {
			chk.Panic("cannot find parameter named %q", name)
		}
		if prm.V < prm.Min {
			chk.Panic("parameter %q has value smaller than minimum. %v < %v is not aceptable", name, prm.V, prm.Min)
		}
		if prm.V > prm.Max {
			chk.Panic("parameter %q has value greater than maximum. %v > %v is not aceptable", name, prm.V, prm.Max)
		}
		if variables[i] == nil {
			chk.Panic("array of variables must not have nil entries")
		}
		*variables[i] = prm.V
	}
	return
}

// Connect connects parameter
func (o *Params) Connect(V *float64, name, caller string) (errorMessage string) {
	prm := o.Find(name)
	if prm == nil {
		return io.Sf("cannot find parameter named %q as requested by %q\n", name, caller)
	}
	prm.Connect(V)
	return
}

// ConnectSet connects set of parameters
func (o *Params) ConnectSet(V []*float64, names []string, caller string) (errorMessage string) {
	chk.IntAssert(len(V), len(names))
	for i, name := range names {
		prm := o.Find(name)
		io.Pforan("name=%v  prm = %v\n", name, prm)
		if prm == nil {
			errorMessage += io.Sf("cannot find parameter named %q as requested by %q\n", name, caller)
		} else {
			prm.Connect(V[i])
		}
	}
	return
}

// ConnectSetOpt connects set of parameters with some being optional
func (o *Params) ConnectSetOpt(V []*float64, names []string, optional []bool, caller string) (errorMessage string) {
	chk.IntAssert(len(V), len(names))
	chk.IntAssert(len(V), len(optional))
	for i, name := range names {
		prm := o.Find(name)
		if prm == nil {
			if !optional[i] {
				errorMessage += io.Sf("cannot find parameter named %q as requested by %q\n", name, caller)
			}
		} else {
			prm.Connect(V[i])
		}
	}
	return
}

// String returns a summary of parameters
func (o Params) String() (l string) {
	for i, prm := range o {
		if i > 0 {
			l += ",\n"
		}
		l += io.Sf("{")
		l += io.Sf(`"n":%q, `, prm.N)
		l += io.Sf(`"v":%v, `, prm.V)
		l += io.Sf(`"min":%v, `, prm.Min)
		l += io.Sf(`"max":%v, `, prm.Max)
		l += io.Sf(`"s":%v, `, prm.S)
		l += io.Sf(`"d":%q, `, prm.D)
		l += io.Sf(`"u":%q, `, prm.U)
		l += io.Sf(`"adj":%v, `, prm.Adj)
		l += io.Sf(`"dep":%v, `, prm.Dep)
		l += io.Sf(`"extra":%q, `, prm.Extra)
		l += io.Sf(`"inact":%v, `, prm.Inact)
		l += io.Sf(`"setdef":%v`, prm.SetDef)
		l += io.Sf("}")
	}
	return
}
<|endoftext|>