<commit_before>package bagit

import (
	"fmt"
	"github.com/APTrust/easy-store/util"
	"sort"
	"strings"
)

// TagFilesRequired => RequiredTags

// BagItProfile is a modified version of bagit-profiles at
// https://github.com/ruebot/bagit-profiles.
type BagItProfile struct {
	// Id is a UUID (as string) that uniquely identifies this profile.
	Id string
	// Name is the name of the profile, usually set by the user in
	// the EasyStore UI.
	Name string
	// AcceptBagItVersion is a list of BagIt versions to accept.
	// For example, ["0.96", "0.97"]
	AcceptBagItVersion []string `json:"acceptBagItVersion"`
	// AcceptSerialization is a list of BagIt serialization formats
	// to accept. For example, ["application/zip", "application/tar"]
	AcceptSerialization []string `json:"acceptSerialization"`
	// AllowFetchTxt indicates whether we allow a fetch.txt file in the bag.
	AllowFetchTxt bool `json:"allowFetchTxt"`
	// AllowMiscTopLevelFiles indicates whether we allow files in the top-level
	// directory other than payload manifests and tag manifests.
	AllowMiscTopLevelFiles bool `json:"allowMiscTopLevelFiles"`
	// AllowMiscDirectories indicates whether we allow miscellaneous
	// directories to exist outside the data directory. These non-data
	// directories often contain custom tag files whose checksums may
	// not appear in any manifest.
	AllowMiscDirectories bool `json:"allowMiscDirectories"`
	// BagItProfileInfo contains descriptive information about this
	// BagIt profile.
	BagItProfileInfo BagItProfileInfo `json:"bagItProfileInfo"`
	// BaseProfileId is the UUID (as string) of the profile on which
	// this profile is based. When you clone a profile in the EasyStore
	// UI, this is id of the profile you cloned.
	BaseProfileId string
	// IsBuiltIn indicates whether this is one of EasyStore's built-in
	// profiles.
	IsBuiltIn bool
	// ManifestsRequired is a list of payload manifests that must be
	// in the bag. Values in this list are the algoritm names. So, to
	// require manifest-md5.txt and manifest-sha256.txt, the list
	// should contain just ["md5", "sha256"].
	ManifestsRequired []string `json:"manifestsRequired"`
	// RequiredTags is a list of TagDefinition objects, each of which defines
	// a tag, its name, which file it must appear in, etc.
	RequiredTags []*TagDefinition `json:"requiredTags"`
	// Serialization can be "required", "optional" or "forbidden."
	Serialization string `json:"serialization"`
	// TagManifestsRequired is a list of required tag manifests. Like
	// ManifestsRequired, the list contains only the names of the
	// required hashing algorithms. E.g. ["md5", "sha256"]
	TagManifestsRequired []string `json:"tagManifestsRequired"`
}

// BagItProfileInfo contains some basic info about the bagit profile
// and the sender, adhering to the structure of bagit-profiles at
// https://github.com/ruebot/bagit-profiles.
type BagItProfileInfo struct {
	// BagItProfileIdentifier is the URL where this bagit profile can be found.
	BagItProfileIdentifier string `json:"bagItProfileIdentifier"`
	// ContactEmail is the email address of the person maintaining this
	// bagit profile.
	ContactEmail string `json:"contactEmail"`
	// ContactName is the name of the person maintaining this profile.
	ContactName string `json:"contactName"`
	// ExternalDescription describes what this profile is for. For example,
	// "BagIt profile for ingesting content into APTrust."
	ExternalDescription string `json:"externalDescription"`
	// SourceOrganization is the name of the organization maintaining this
	// profile.
	SourceOrganization string `json:"sourceOrganization"`
	// Version is the version number of this profile. E.g "1.2".
	Version string `json:"Version"`
}

// LoadBagItProfile loads a BagItProfile from the specified file path.
func LoadBagItProfile(filePath string) (*BagItProfile, error) {
	profile := &BagItProfile{}
	err := util.LoadJson(filePath, profile)
	return profile, err
}

// Validate returns a list of errors describing why the profile is not
// valid. If the profile is valid, this returns an empty slice.
func (profile *BagItProfile) Validate() []error {
	errs := make([]error, 0)
	if profile.AcceptBagItVersion == nil || len(profile.AcceptBagItVersion) == 0 {
		errs = append(errs, fmt.Errorf("acceptBagItVersion must accept at least one BagIt version."))
	}
	if profile.ManifestsRequired == nil || len(profile.ManifestsRequired) == 0 {
		errs = append(errs, fmt.Errorf("manifestsRequired must require at least one algorithm."))
	}
	if !profile.RequiresTagFile("bagit.txt") {
		errs = append(errs, fmt.Errorf("requiredTags is missing requirements for bagit.txt."))
	}
	if !profile.RequiresTagFile("bag-info.txt") {
		errs = append(errs, fmt.Errorf("requiredTags is missing requirements for bag-info.txt."))
	}
	return errs
}

func (profile *BagItProfile) RequiresTagFile(filename string) bool {
	for _, tag := range profile.RequiredTags {
		if tag.TagFile == filename {
			return true
		}
	}
	return false
}

// RequiredTagDirs returns a list of directories that the profile says
// should contain required tag files. The validator should permit the
// presence of these directories even when AllowMiscDirectories is false.
func (profile *BagItProfile) RequiredTagDirs() []string {
	dirs := make([]string, 0)
	for _, tag := range profile.RequiredTags {
		// Use "/" instead of os.PathSeparator, because BagIt spec
		// says manifests and tag manifests should use "/".
		parts := strings.Split(tag.TagFile, "/")
		if len(parts) > 1 && !util.StringListContains(dirs, parts[0]) {
			dirs = append(dirs, parts[0])
		}
	}
	return dirs
}

// SortedTagFileNames returns a sorted list of required tag file
// names. Each item in the list is the relative path of a tag file
// within the bag. E.g. bag-info.txt or dpn-tags/dpn-info.txt.
func (profile *BagItProfile) SortedTagFilesRequired() []string {
	fileMap := make(map[string]bool)
	for _, tag := range profile.RequiredTags {
		fileMap[tag.TagFile] = true
	}
	fileNames := make([]string, len(fileMap))
	i := 0
	for fileName := range fileMap {
		fileNames[i] = fileName
		i++
	}
	sort.Strings(fileNames)
	return fileNames
}

// SortedTagNames returns a sorted list of tag names with the
// specified required tag file. Param relFilePath should be something like
// "bag-info.txt" or "dpn-tags/dpn-info.txt". If relFilePath is not a
// required tag file, this will return an empty list.
func (profile *BagItProfile) SortedTagNames(relFilePath string) []string {
	nameMap := make(map[string]bool)
	for _, tag := range profile.RequiredTags {
		nameMap[tag.TagName] = true
	}
	tagNames := make([]string, len(nameMap))
	i := 0
	for tagName := range nameMap {
		tagNames[i] = tagName
		i++
	}
	sort.Strings(tagNames)
	return tagNames
}

func (profile *BagItProfile) TagsForFile(relFilePath string) []*TagDefinition {
	tags := make([]*TagDefinition, 0)
	for _, tag := range profile.RequiredTags {
		if tag.TagFile == relFilePath {
			tags = append(tags, tag)
		}
	}
	return tags
}

func (profile *BagItProfile) FindTagDef(relFilePath, tagName string) *TagDefinition {
	var matchingTag *TagDefinition
	for _, tag := range profile.RequiredTags {
		if tag.TagFile == relFilePath && tag.TagName == tagName {
			matchingTag = tag
		}
	}
	return matchingTag
}
<commit_msg>Fixed SortedTagNames<commit_after>package bagit

import (
	"fmt"
	"github.com/APTrust/easy-store/util"
	"sort"
	"strings"
)

// TagFilesRequired => RequiredTags

// BagItProfile is a modified version of bagit-profiles at
// https://github.com/ruebot/bagit-profiles.
type BagItProfile struct {
	// Id is a UUID (as string) that uniquely identifies this profile.
	Id string
	// Name is the name of the profile, usually set by the user in
	// the EasyStore UI.
	Name string
	// AcceptBagItVersion is a list of BagIt versions to accept.
	// For example, ["0.96", "0.97"]
	AcceptBagItVersion []string `json:"acceptBagItVersion"`
	// AcceptSerialization is a list of BagIt serialization formats
	// to accept. For example, ["application/zip", "application/tar"]
	AcceptSerialization []string `json:"acceptSerialization"`
	// AllowFetchTxt indicates whether we allow a fetch.txt file in the bag.
	AllowFetchTxt bool `json:"allowFetchTxt"`
	// AllowMiscTopLevelFiles indicates whether we allow files in the top-level
	// directory other than payload manifests and tag manifests.
	AllowMiscTopLevelFiles bool `json:"allowMiscTopLevelFiles"`
	// AllowMiscDirectories indicates whether we allow miscellaneous
	// directories to exist outside the data directory. These non-data
	// directories often contain custom tag files whose checksums may
	// not appear in any manifest.
	AllowMiscDirectories bool `json:"allowMiscDirectories"`
	// BagItProfileInfo contains descriptive information about this
	// BagIt profile.
	BagItProfileInfo BagItProfileInfo `json:"bagItProfileInfo"`
	// BaseProfileId is the UUID (as string) of the profile on which
	// this profile is based. When you clone a profile in the EasyStore
	// UI, this is id of the profile you cloned.
	BaseProfileId string
	// IsBuiltIn indicates whether this is one of EasyStore's built-in
	// profiles.
	IsBuiltIn bool
	// ManifestsRequired is a list of payload manifests that must be
	// in the bag. Values in this list are the algoritm names. So, to
	// require manifest-md5.txt and manifest-sha256.txt, the list
	// should contain just ["md5", "sha256"].
	ManifestsRequired []string `json:"manifestsRequired"`
	// RequiredTags is a list of TagDefinition objects, each of which defines
	// a tag, its name, which file it must appear in, etc.
	RequiredTags []*TagDefinition `json:"requiredTags"`
	// Serialization can be "required", "optional" or "forbidden."
	Serialization string `json:"serialization"`
	// TagManifestsRequired is a list of required tag manifests. Like
	// ManifestsRequired, the list contains only the names of the
	// required hashing algorithms. E.g. ["md5", "sha256"]
	TagManifestsRequired []string `json:"tagManifestsRequired"`
}

// BagItProfileInfo contains some basic info about the bagit profile
// and the sender, adhering to the structure of bagit-profiles at
// https://github.com/ruebot/bagit-profiles.
type BagItProfileInfo struct {
	// BagItProfileIdentifier is the URL where this bagit profile can be found.
	BagItProfileIdentifier string `json:"bagItProfileIdentifier"`
	// ContactEmail is the email address of the person maintaining this
	// bagit profile.
	ContactEmail string `json:"contactEmail"`
	// ContactName is the name of the person maintaining this profile.
	ContactName string `json:"contactName"`
	// ExternalDescription describes what this profile is for. For example,
	// "BagIt profile for ingesting content into APTrust."
	ExternalDescription string `json:"externalDescription"`
	// SourceOrganization is the name of the organization maintaining this
	// profile.
	SourceOrganization string `json:"sourceOrganization"`
	// Version is the version number of this profile. E.g "1.2".
	Version string `json:"Version"`
}

// LoadBagItProfile loads a BagItProfile from the specified file path.
func LoadBagItProfile(filePath string) (*BagItProfile, error) {
	profile := &BagItProfile{}
	err := util.LoadJson(filePath, profile)
	return profile, err
}

// Validate returns a list of errors describing why the profile is not
// valid. If the profile is valid, this returns an empty slice.
func (profile *BagItProfile) Validate() []error {
	errs := make([]error, 0)
	if profile.AcceptBagItVersion == nil || len(profile.AcceptBagItVersion) == 0 {
		errs = append(errs, fmt.Errorf("acceptBagItVersion must accept at least one BagIt version."))
	}
	if profile.ManifestsRequired == nil || len(profile.ManifestsRequired) == 0 {
		errs = append(errs, fmt.Errorf("manifestsRequired must require at least one algorithm."))
	}
	if !profile.RequiresTagFile("bagit.txt") {
		errs = append(errs, fmt.Errorf("requiredTags is missing requirements for bagit.txt."))
	}
	if !profile.RequiresTagFile("bag-info.txt") {
		errs = append(errs, fmt.Errorf("requiredTags is missing requirements for bag-info.txt."))
	}
	return errs
}

func (profile *BagItProfile) RequiresTagFile(filename string) bool {
	for _, tag := range profile.RequiredTags {
		if tag.TagFile == filename {
			return true
		}
	}
	return false
}

// RequiredTagDirs returns a list of directories that the profile says
// should contain required tag files. The validator should permit the
// presence of these directories even when AllowMiscDirectories is false.
func (profile *BagItProfile) RequiredTagDirs() []string {
	dirs := make([]string, 0)
	for _, tag := range profile.RequiredTags {
		// Use "/" instead of os.PathSeparator, because BagIt spec
		// says manifests and tag manifests should use "/".
		parts := strings.Split(tag.TagFile, "/")
		if len(parts) > 1 && !util.StringListContains(dirs, parts[0]) {
			dirs = append(dirs, parts[0])
		}
	}
	return dirs
}

// SortedTagFileNames returns a sorted list of required tag file
// names. Each item in the list is the relative path of a tag file
// within the bag. E.g. bag-info.txt or dpn-tags/dpn-info.txt.
func (profile *BagItProfile) SortedTagFilesRequired() []string {
	fileMap := make(map[string]bool)
	for _, tag := range profile.RequiredTags {
		fileMap[tag.TagFile] = true
	}
	fileNames := make([]string, len(fileMap))
	i := 0
	for fileName := range fileMap {
		fileNames[i] = fileName
		i++
	}
	sort.Strings(fileNames)
	return fileNames
}

// SortedTagNames returns a sorted list of tag names with the
// specified required tag file. Param relFilePath should be something like
// "bag-info.txt" or "dpn-tags/dpn-info.txt". If relFilePath is not a
// required tag file, this will return an empty list.
func (profile *BagItProfile) SortedTagNames(relFilePath string) []string {
	nameMap := make(map[string]bool)
	for _, tag := range profile.RequiredTags {
		if tag.TagFile == relFilePath {
			nameMap[tag.TagName] = true
		}
	}
	tagNames := make([]string, len(nameMap))
	i := 0
	for tagName := range nameMap {
		tagNames[i] = tagName
		i++
	}
	sort.Strings(tagNames)
	return tagNames
}

func (profile *BagItProfile) TagsForFile(relFilePath string) []*TagDefinition {
	tags := make([]*TagDefinition, 0)
	for _, tag := range profile.RequiredTags {
		if tag.TagFile == relFilePath {
			tags = append(tags, tag)
		}
	}
	return tags
}

func (profile *BagItProfile) FindTagDef(relFilePath, tagName string) *TagDefinition {
	var matchingTag *TagDefinition
	for _, tag := range profile.RequiredTags {
		if tag.TagFile == relFilePath && tag.TagName == tagName {
			matchingTag = tag
		}
	}
	return matchingTag
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"net"

	"github.com/brutella/hc/hap"
	"github.com/brutella/hc/model"
	"github.com/brutella/hc/model/accessory"
)

type Device struct {
	Name      string
	HouseCode string
	DeviceID  int
	Dimmable  bool
}

var bulbs = []Device{Device{
	Name:      "Bed Lamp",
	HouseCode: "C",
	DeviceID:  10,
	Dimmable:  true,
}, Device{
	Name:      "Corner Lamp",
	HouseCode: "C",
	DeviceID:  8,
	Dimmable:  true,
}, Device{
	Name:      "Couch Lights",
	HouseCode: "C",
	DeviceID:  6,
	Dimmable:  true,
}, Device{
	Name:      "Desk Lights",
	HouseCode: "C",
	DeviceID:  2,
	Dimmable:  true,
}, Device{
	Name:      "Dining Room",
	HouseCode: "C",
	DeviceID:  4,
	Dimmable:  true,
}, Device{
	Name:      "Fireplace Lights",
	HouseCode: "C",
	DeviceID:  1,
	Dimmable:  false,
}, Device{
	Name:      "Lava Lamps",
	HouseCode: "E",
	DeviceID:  1,
	Dimmable:  false,
}, Device{
	Name:      "TV Lights",
	HouseCode: "C",
	DeviceID:  7,
	Dimmable:  true,
}}

func InstallX10Devices() {
	for _, b := range bulbs {
		go func(b Device) {
			log.Printf("Installing X10 device \"%v\"...\n", b.Name)

			info := model.Info{
				Name:         b.Name,
				Manufacturer: "X10",
			}

			light := accessory.NewLightBulb(info)
			light.OnStateChanged(func(on bool) {
				var action string
				if on {
					action = "on"
				} else {
					action = "off"
				}
				var method string
				if b.Dimmable {
					method = "pl"
				} else {
					method = "rf"
				}

				cmd := fmt.Sprintf("%s %s%i %s", method, b.HouseCode, b.DeviceID, action)
				writeCommand(cmd)
			})

			t, err := hap.NewIPTransport("10000000", light.Accessory)
			if err != nil {
				log.Fatal(err)
			}

			t.Start()
		}(b)
	}
}

func writeCommand(cmd string) {
	// TODO: Queue commands and execute serially with a delay
	conn, err := net.Dial("tcp", "localhost:1099")
	if err != nil {
		log.Println(err)
	}
	defer conn.Close()

	writer := bufio.NewWriter(conn)
	_, err = writer.WriteString(cmd)
	if err != nil {
		log.Println(err)
	}
}
<commit_msg>RIP type system<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"net"

	"github.com/brutella/hc/hap"
	"github.com/brutella/hc/model"
	"github.com/brutella/hc/model/accessory"
)

type Device struct {
	Name      string
	HouseCode string
	DeviceID  int
	Dimmable  bool
}

var bulbs = []Device{Device{
	Name:      "Bed Lamp",
	HouseCode: "C",
	DeviceID:  10,
	Dimmable:  true,
}, Device{
	Name:      "Corner Lamp",
	HouseCode: "C",
	DeviceID:  8,
	Dimmable:  true,
}, Device{
	Name:      "Couch Lights",
	HouseCode: "C",
	DeviceID:  6,
	Dimmable:  true,
}, Device{
	Name:      "Desk Lights",
	HouseCode: "C",
	DeviceID:  2,
	Dimmable:  true,
}, Device{
	Name:      "Dining Room",
	HouseCode: "C",
	DeviceID:  4,
	Dimmable:  true,
}, Device{
	Name:      "Fireplace Lights",
	HouseCode: "C",
	DeviceID:  1,
	Dimmable:  false,
}, Device{
	Name:      "Lava Lamps",
	HouseCode: "E",
	DeviceID:  1,
	Dimmable:  false,
}, Device{
	Name:      "TV Lights",
	HouseCode: "C",
	DeviceID:  7,
	Dimmable:  true,
}}

func InstallX10Devices() {
	lightBulbs := []interface{}{}

	for _, b := range bulbs {
		log.Printf("Installing X10 device \"%v\"...\n", b.Name)

		info := model.Info{
			Name:         b.Name,
			Manufacturer: "X10",
		}

		light := accessory.NewLightBulb(info)
		light.OnStateChanged(func(on bool) {
			var action string
			if on {
				action = "on"
			} else {
				action = "off"
			}
			var method string
			if b.Dimmable {
				method = "pl"
			} else {
				method = "rf"
			}

			cmd := fmt.Sprintf("%s %s%i %s", method, b.HouseCode, b.DeviceID, action)
			writeCommand(cmd)
		})

		lightBulbs = append(lightBulbs, light.Accessory)
	}

	accessories := make([]*accessory.Accessory, len(lightBulbs))
	for i, bulb := range lightBulbs {
		accessories[i] = bulb.(*accessory.Accessory)
	}

	t, err := hap.NewIPTransport("10000000", accessories[0], accessories[1:]...)
	if err != nil {
		log.Fatal(err)
	}

	t.Start()
}

func writeCommand(cmd string) {
	// TODO: Queue commands and execute serially with a delay
	conn, err := net.Dial("tcp", "localhost:1099")
	if err != nil {
		log.Println(err)
	}
	defer conn.Close()

	writer := bufio.NewWriter(conn)
	_, err = writer.WriteString(cmd)
	if err != nil {
		log.Println(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/base64"
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"syscall"

	"github.com/jaxxstorm/flexvolume"
	"github.com/kolyshkin/goploop-cli"
	"github.com/urfave/cli"
	"github.com/virtuozzo/ploop-flexvol/vstorage"

	"github.com/golang/glog"
)

func setup_journld() ([]string, *exec.Cmd, error) {
	fd, err := syscall.Dup(syscall.Stdout)
	if err != nil {
		return nil, nil, err
	}

	syscall.CloseOnExec(fd)

	flexvolume.SetRespFile(os.NewFile((uintptr)(fd), "RespFile"))

	flag.CommandLine.Parse([]string{"-logtostderr"})

	cmd := exec.Command("systemd-cat", "--identifier", "ploop-flexvol")
	if err != nil {
		return nil, nil, err
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, nil, fmt.Errorf("Unable to create a pipe: %v", err)
	}
	cmd.Stdin = pr
	defer pr.Close()
	defer pw.Close()

	if err := syscall.Dup2(int(pw.Fd()), syscall.Stdout); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stdout: %v", err)
	}
	if err := syscall.Dup2(syscall.Stdout, syscall.Stderr); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stderr: %v", err)
	}
	if err := cmd.Start(); err != nil {
		return nil, nil, fmt.Errorf("Unable to start systemd-cat: %v", err)
	}
	return os.Args, cmd, nil
}

func setup_wrapper_logging() ([]string, *exec.Cmd, error) {
	syscall.CloseOnExec(3)
	flexvolume.SetRespFile(os.NewFile((uintptr)(3), "RespFile"))
	flag.CommandLine.Parse(os.Args[2:])
	return flag.CommandLine.Args(), nil, nil
}

func setup_logging() ([]string, *exec.Cmd, error) {
	if os.Args[1] == "wrapper" {
		return setup_wrapper_logging()
	}

	return setup_journld()
}

func main() {
	args, cmd, err := setup_logging()
	if err != nil {
		panic(err)
	}
	if cmd != nil {
		defer func() {
			syscall.Close(syscall.Stdout)
			syscall.Close(syscall.Stderr)
			cmd.Wait()
		}()
	}

	app := cli.NewApp()
	app.Name = "ploop flexvolume"
	app.Usage = "Mount ploop volumes in kubernetes using the flexvolume driver"
	app.Commands = flexvolume.Commands(Ploop{})
	app.CommandNotFound = flexvolume.CommandNotFound
	app.Authors = []cli.Author{
		cli.Author{
			Name: "Lee Briggs",
		},
		cli.Author{
			Name: "Virtuozzo",
		},
	}
	app.Version = "0.2a"

	glog.Infof("Request: %v", args)
	app.Run(args)
}

type Ploop struct{}

const WorkingDir = "/var/run/ploop-flexvol/"

func (p Ploop) Init() (*flexvolume.Response, error) {
	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Ploop is available",
	}, nil
}

func (p Ploop) path(options map[string]string) string {
	path := "/"
	if options["volumePath"] != "" {
		path += options["volumePath"] + "/"
	}
	path += options["volumeId"]
	return path
}

func (p Ploop) GetVolumeName(options map[string]string) (*flexvolume.Response, error) {
	if options["volumeId"] == "" {
		return nil, fmt.Errorf("Must specify a volume id")
	}

	return &flexvolume.Response{
		Status:     flexvolume.StatusSuccess,
		VolumeName: options["volumeId"],
	}, nil
}

func prepareVstorage(clusterName, clusterPasswd string, mount string) error {
	mounted, _ := vstorage.IsVstorage(mount)
	if mounted {
		return nil
	}

	// not mounted in proper place, prepare mount place and check other
	// mounts
	if err := os.MkdirAll(mount, 0755); err != nil {
		return err
	}

	v := vstorage.Vstorage{clusterName}
	p, _ := v.Mountpoint()
	if p != "" {
		return syscall.Mount(p, mount, "", syscall.MS_BIND, "")
	}

	if clusterPasswd == "" {
		return errors.New("Please provide vstorage credentials")
	}

	if err := v.Auth(clusterPasswd); err != nil {
		return err
	}
	if err := v.Mount(mount); err != nil {
		return err
	}

	return nil
}

func (p Ploop) Mount(target string, options map[string]string) (*flexvolume.Response, error) {
	// make the target directory we're going to mount to
	err := os.MkdirAll(target, 0755)
	if err != nil {
		return nil, err
	}

	path := p.path(options)

	if options["kubernetes.io/secret/clusterName"] != "" {
		_cluster, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterName"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster name: %v", err.Error())
		}
		cluster := string(_cluster)

		_passwd, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterPassword"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster password: %v", err.Error())
		}
		passwd := string(_passwd)

		mount := WorkingDir + cluster
		if err := prepareVstorage(cluster, passwd, mount); err != nil {
			return nil, err
		}
		path = mount + path
	}
	// open the disk descriptor first
	volume, err := ploop.Open(path + "/" + "DiskDescriptor.xml")
	if err != nil {
		return nil, err
	}
	defer volume.Close()

	if m, _ := volume.IsMounted(); !m {
		// If it's mounted, let's mount it!

		readonly := false
		if options["kubernetes.io/readwrite"] == "ro" {
			readonly = true
		}

		mp := ploop.MountParam{Target: target, Readonly: readonly}

		_, err := volume.Mount(&mp)
		if err != nil {
			return nil, err
		}

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Successfully mounted the ploop volume",
		}, nil
	} else {

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Ploop volume already mounted",
		}, nil

	}
}

func (p Ploop) Unmount(mount string) (*flexvolume.Response, error) {
	if err := ploop.UmountByMount(mount); err != nil {
		return nil, err
	}

	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully unmounted the ploop volume",
	}, nil
}
<commit_msg>Fix volumeId to volumeID naming<commit_after>package main

import (
	"encoding/base64"
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"syscall"

	"github.com/jaxxstorm/flexvolume"
	"github.com/kolyshkin/goploop-cli"
	"github.com/urfave/cli"
	"github.com/virtuozzo/ploop-flexvol/vstorage"

	"github.com/golang/glog"
)

func setup_journld() ([]string, *exec.Cmd, error) {
	fd, err := syscall.Dup(syscall.Stdout)
	if err != nil {
		return nil, nil, err
	}

	syscall.CloseOnExec(fd)

	flexvolume.SetRespFile(os.NewFile((uintptr)(fd), "RespFile"))

	flag.CommandLine.Parse([]string{"-logtostderr"})

	cmd := exec.Command("systemd-cat", "--identifier", "ploop-flexvol")
	if err != nil {
		return nil, nil, err
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, nil, fmt.Errorf("Unable to create a pipe: %v", err)
	}
	cmd.Stdin = pr
	defer pr.Close()
	defer pw.Close()

	if err := syscall.Dup2(int(pw.Fd()), syscall.Stdout); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stdout: %v", err)
	}
	if err := syscall.Dup2(syscall.Stdout, syscall.Stderr); err != nil {
		return nil, nil, fmt.Errorf("Unable to redirect stderr: %v", err)
	}
	if err := cmd.Start(); err != nil {
		return nil, nil, fmt.Errorf("Unable to start systemd-cat: %v", err)
	}
	return os.Args, cmd, nil
}

func setup_wrapper_logging() ([]string, *exec.Cmd, error) {
	syscall.CloseOnExec(3)
	flexvolume.SetRespFile(os.NewFile((uintptr)(3), "RespFile"))
	flag.CommandLine.Parse(os.Args[2:])
	return flag.CommandLine.Args(), nil, nil
}

func setup_logging() ([]string, *exec.Cmd, error) {
	if os.Args[1] == "wrapper" {
		return setup_wrapper_logging()
	}

	return setup_journld()
}

func main() {
	args, cmd, err := setup_logging()
	if err != nil {
		panic(err)
	}
	if cmd != nil {
		defer func() {
			syscall.Close(syscall.Stdout)
			syscall.Close(syscall.Stderr)
			cmd.Wait()
		}()
	}

	app := cli.NewApp()
	app.Name = "ploop flexvolume"
	app.Usage = "Mount ploop volumes in kubernetes using the flexvolume driver"
	app.Commands = flexvolume.Commands(Ploop{})
	app.CommandNotFound = flexvolume.CommandNotFound
	app.Authors = []cli.Author{
		cli.Author{
			Name: "Lee Briggs",
		},
		cli.Author{
			Name: "Virtuozzo",
		},
	}
	app.Version = "0.2a"

	glog.Infof("Request: %v", args)
	app.Run(args)
}

type Ploop struct{}

const WorkingDir = "/var/run/ploop-flexvol/"

func (p Ploop) Init() (*flexvolume.Response, error) {
	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Ploop is available",
	}, nil
}

func (p Ploop) path(options map[string]string) string {
	path := "/"
	if options["volumePath"] != "" {
		path += options["volumePath"] + "/"
	}
	path += options["volumeID"]
	return path
}

func (p Ploop) GetVolumeName(options map[string]string) (*flexvolume.Response, error) {
	if options["volumeID"] == "" {
		return nil, fmt.Errorf("Must specify a volume id")
	}

	return &flexvolume.Response{
		Status:     flexvolume.StatusSuccess,
		VolumeName: options["volumeID"],
	}, nil
}

func prepareVstorage(clusterName, clusterPasswd string, mount string) error {
	mounted, _ := vstorage.IsVstorage(mount)
	if mounted {
		return nil
	}

	// not mounted in proper place, prepare mount place and check other
	// mounts
	if err := os.MkdirAll(mount, 0755); err != nil {
		return err
	}

	v := vstorage.Vstorage{clusterName}
	p, _ := v.Mountpoint()
	if p != "" {
		return syscall.Mount(p, mount, "", syscall.MS_BIND, "")
	}

	if clusterPasswd == "" {
		return errors.New("Please provide vstorage credentials")
	}

	if err := v.Auth(clusterPasswd); err != nil {
		return err
	}
	if err := v.Mount(mount); err != nil {
		return err
	}

	return nil
}

func (p Ploop) Mount(target string, options map[string]string) (*flexvolume.Response, error) {
	// make the target directory we're going to mount to
	err := os.MkdirAll(target, 0755)
	if err != nil {
		return nil, err
	}

	path := p.path(options)

	if options["kubernetes.io/secret/clusterName"] != "" {
		_cluster, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterName"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster name: %v", err.Error())
		}
		cluster := string(_cluster)

		_passwd, err := base64.StdEncoding.DecodeString(options["kubernetes.io/secret/clusterPassword"])
		if err != nil {
			return nil, fmt.Errorf("Unable to decode a cluster password: %v", err.Error())
		}
		passwd := string(_passwd)

		mount := WorkingDir + cluster
		if err := prepareVstorage(cluster, passwd, mount); err != nil {
			return nil, err
		}
		path = mount + path
	}
	// open the disk descriptor first
	volume, err := ploop.Open(path + "/" + "DiskDescriptor.xml")
	if err != nil {
		return nil, err
	}
	defer volume.Close()

	if m, _ := volume.IsMounted(); !m {
		// If it's mounted, let's mount it!

		readonly := false
		if options["kubernetes.io/readwrite"] == "ro" {
			readonly = true
		}

		mp := ploop.MountParam{Target: target, Readonly: readonly}

		_, err := volume.Mount(&mp)
		if err != nil {
			return nil, err
		}

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Successfully mounted the ploop volume",
		}, nil
	} else {

		return &flexvolume.Response{
			Status:  flexvolume.StatusSuccess,
			Message: "Ploop volume already mounted",
		}, nil

	}
}

func (p Ploop) Unmount(mount string) (*flexvolume.Response, error) {
	if err := ploop.UmountByMount(mount); err != nil {
		return nil, err
	}

	return &flexvolume.Response{
		Status:  flexvolume.StatusSuccess,
		Message: "Successfully unmounted the ploop volume",
	}, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/zero-boilerplate/go-api-helpers/service"
	"path/filepath"

	service2 "github.com/ayufan/golang-kardianos-service"
)

type app struct {
	logger             service2.Logger
	watcherDoneChannel chan bool
}

func (a *app) OnStop() {
	defer recover()
	close(a.watcherDoneChannel)
}

func (a *app) Run(logger service2.Logger) {
	a.logger = logger
	defer func() {
		if r := recover(); r != nil {
			a.logger.Errorf("Run app error: %s", getStringFromRecovery(r))
		}
	}()

	userHomeDir := getUserHomeDir()
	watchDir := filepath.Join(userHomeDir, ".script-watcher", "scripts")
	if !doesDirExist(watchDir) {
		panic(fmt.Sprintf("The watch dir '%s' does not exist", watchDir))
		return
	}

	a.scanDirForExistingFile(watchDir)
	a.startWatching(watchDir)
}

func main() {
	a := &app{}
	service.NewServiceRunnerBuilder("Script Watcher", a).WithOnStopHandler(a).WithServiceUserName_AsCurrentUser().Run()
}
<commit_msg>Check NIL channel. This will happen if it did not yet get to starting to watch the directory.<commit_after>package main

import (
	"fmt"
	"github.com/zero-boilerplate/go-api-helpers/service"
	"path/filepath"

	service2 "github.com/ayufan/golang-kardianos-service"
)

type app struct {
	logger             service2.Logger
	watcherDoneChannel chan bool
}

func (a *app) OnStop() {
	defer recover()
	if a.watcherDoneChannel != nil {
		close(a.watcherDoneChannel)
	}
}

func (a *app) Run(logger service2.Logger) {
	a.logger = logger
	defer func() {
		if r := recover(); r != nil {
			a.logger.Errorf("Run app error: %s", getStringFromRecovery(r))
		}
	}()

	userHomeDir := getUserHomeDir()
	watchDir := filepath.Join(userHomeDir, ".script-watcher", "scripts")
	if !doesDirExist(watchDir) {
		panic(fmt.Sprintf("The watch dir '%s' does not exist", watchDir))
		return
	}

	a.scanDirForExistingFile(watchDir)
	a.startWatching(watchDir)
}

func main() {
	a := &app{}
	service.NewServiceRunnerBuilder("Script Watcher", a).WithOnStopHandler(a).WithServiceUserName_AsCurrentUser().Run()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"

	"github.com/alecthomas/kingpin"
	"github.com/getantibody/antibody/antibodylib"
	"github.com/getantibody/antibody/project"
	"github.com/getantibody/antibody/shell"
	"golang.org/x/crypto/ssh/terminal"
)

var (
	version = "dev"

	app         = kingpin.New("antibody", "The fastest shell plugin manager")
	parallelism = app.Flag("parallelism", "max amount of tasks to launch in parallel").
			Short('p').
			Default(strconv.Itoa(runtime.NumCPU())).
			Int()
	bundleCmd = app.Command("bundle", "downloads a bundle and prints its source line")
	bundles   = bundleCmd.Arg("bundles", "bundle list").Strings()
	updateCmd = app.Command("update", "updates all previously bundled bundles")
	homeCmd   = app.Command("home", "prints where antibody is cloning the bundles")
	purgeCmd  = app.Command("purge", "purges a bundle from your computer")
	purgee    = purgeCmd.Arg("bundle", "bundle to be purged").String()
	listCmd   = app.Command("list", "lists all currently instaled bundles").Alias("ls")
	initCmd   = app.Command("init", "initializes the shell so Antibody can work as expected")
)

func main() {
	app.Author("Carlos Alexandro Becker <caarlos0@gmail.com>")
	app.Version("antibody version " + version)
	app.VersionFlag.Short('v')
	app.HelpFlag.Short('h')

	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case bundleCmd.FullCommand():
		bundle()
	case updateCmd.FullCommand():
		update()
	case homeCmd.FullCommand():
		fmt.Println(antibodylib.Home())
	case purgeCmd.FullCommand():
		purge()
	case listCmd.FullCommand():
		list()
	case initCmd.FullCommand():
		sh, err := shell.Init()
		app.FatalIfError(err, "failed to init")
		fmt.Println(sh)
	}
}

func bundle() {
	var input io.Reader
	if !terminal.IsTerminal(int(os.Stdin.Fd())) && len(*bundles) == 0 {
		input = os.Stdin
	} else {
		input = bytes.NewBufferString(strings.Join(*bundles, " "))
	}
	sh, err := antibodylib.New(antibodylib.Home(), input, *parallelism).Bundle()
	app.FatalIfError(err, "failed to bundle")
	fmt.Println(sh)
}

func update() {
	var home = antibodylib.Home()
	fmt.Printf("Updating all bundles in %v...\n", home)
	var err = project.Update(home, *parallelism)
	app.FatalIfError(err, "failed to update")
}

func purge() {
	fmt.Println("Removing", *purgee)
	var err = os.RemoveAll(project.New(antibodylib.Home(), *purgee).Folder())
	app.FatalIfError(err, "failed to purge")
}

func list() {
	home := antibodylib.Home()
	projects, err := project.List(home)
	app.FatalIfError(err, "failed to list bundles")
	for _, b := range projects {
		fmt.Println(filepath.Join(home, b))
	}
}
<commit_msg>fixing parallelism to 4<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

	"github.com/alecthomas/kingpin"
	"github.com/getantibody/antibody/antibodylib"
	"github.com/getantibody/antibody/project"
	"github.com/getantibody/antibody/shell"
	"golang.org/x/crypto/ssh/terminal"
)

var (
	version = "dev"

	app         = kingpin.New("antibody", "The fastest shell plugin manager")
	parallelism = app.Flag("parallelism", "max amount of tasks to launch in parallel").
			Short('p').
			Default(4).
			Int()
	bundleCmd = app.Command("bundle", "downloads a bundle and prints its source line")
	bundles   = bundleCmd.Arg("bundles", "bundle list").Strings()
	updateCmd = app.Command("update", "updates all previously bundled bundles")
	homeCmd   = app.Command("home", "prints where antibody is cloning the bundles")
	purgeCmd  = app.Command("purge", "purges a bundle from your computer")
	purgee    = purgeCmd.Arg("bundle", "bundle to be purged").String()
	listCmd   = app.Command("list", "lists all currently instaled bundles").Alias("ls")
	initCmd   = app.Command("init", "initializes the shell so Antibody can work as expected")
)

func main() {
	app.Author("Carlos Alexandro Becker <caarlos0@gmail.com>")
	app.Version("antibody version " + version)
	app.VersionFlag.Short('v')
	app.HelpFlag.Short('h')

	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
	case bundleCmd.FullCommand():
		bundle()
	case updateCmd.FullCommand():
		update()
	case homeCmd.FullCommand():
		fmt.Println(antibodylib.Home())
	case purgeCmd.FullCommand():
		purge()
	case listCmd.FullCommand():
		list()
	case initCmd.FullCommand():
		sh, err := shell.Init()
		app.FatalIfError(err, "failed to init")
		fmt.Println(sh)
	}
}

func bundle() {
	var input io.Reader
	if !terminal.IsTerminal(int(os.Stdin.Fd())) && len(*bundles) == 0 {
		input = os.Stdin
	} else {
		input = bytes.NewBufferString(strings.Join(*bundles, " "))
	}
	sh, err := antibodylib.New(antibodylib.Home(), input, *parallelism).Bundle()
	app.FatalIfError(err, "failed to bundle")
	fmt.Println(sh)
}

func update() {
	var home = antibodylib.Home()
	fmt.Printf("Updating all bundles in %v...\n", home)
	var err = project.Update(home, *parallelism)
	app.FatalIfError(err, "failed to update")
}

func purge() {
	fmt.Println("Removing", *purgee)
	var err = os.RemoveAll(project.New(antibodylib.Home(), *purgee).Folder())
	app.FatalIfError(err, "failed to purge")
}

func list() {
	home := antibodylib.Home()
	projects, err := project.List(home)
	app.FatalIfError(err, "failed to list bundles")
	for _, b := range projects {
		fmt.Println(filepath.Join(home, b))
	}
}
<|endoftext|>


<commit_before>package main // import "moul.io/protoc-gen-gotemplate"

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

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/protoc-gen-go/generator"
	plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
	ggdescriptor "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"

	pgghelpers "moul.io/protoc-gen-gotemplate/helpers"
)

var (
	registry *ggdescriptor.Registry // some helpers need access to registry
)

const (
	boolTrue  = "true"
	boolFalse = "false"
)

func main() {
	g := generator.New()

	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		g.Error(err, "reading input")
	}

	if err = proto.Unmarshal(data, g.Request); err != nil {
		g.Error(err, "parsing input proto")
	}

	if len(g.Request.FileToGenerate) == 0 {
		g.Fail("no files to generate")
	}

	g.CommandLineParameters(g.Request.GetParameter())

	// Parse parameters
	var (
		templateDir       = "./templates"
		destinationDir    = "."
		debug             = false
		all               = false
		singlePackageMode = false
	)
	if parameter := g.Request.GetParameter(); parameter != "" {
		for _, param := range strings.Split(parameter, ",") {
			parts := strings.Split(param, "=")
			if len(parts) != 2 {
				log.Printf("Err: invalid parameter: %q", param)
				continue
			}
			switch parts[0] {
			case "template_dir":
				templateDir = parts[1]
			case "destination_dir":
				destinationDir = parts[1]
			case "single-package-mode":
				switch strings.ToLower(parts[1]) {
				case boolTrue, "t":
					singlePackageMode = true
				case boolFalse, "f":
				default:
					log.Printf("Err: invalid value for single-package-mode: %q", parts[1])
				}
			case "debug":
				switch strings.ToLower(parts[1]) {
				case boolTrue, "t":
					debug = true
				case boolFalse, "f":
				default:
					log.Printf("Err: invalid value for debug: %q", parts[1])
				}
			case "all":
				switch strings.ToLower(parts[1]) {
				case boolTrue, "t":
					all = true
				case boolFalse, "f":
				default:
					log.Printf("Err: invalid value for debug: %q", parts[1])
				}
			default:
				log.Printf("Err: unknown parameter: %q", param)
			}
		}
	}

	tmplMap := make(map[string]*plugin_go.CodeGeneratorResponse_File)
	concatOrAppend := func(file *plugin_go.CodeGeneratorResponse_File) {
		if val, ok := tmplMap[file.GetName()]; ok {
			*val.Content += file.GetContent()
		} else {
			tmplMap[file.GetName()] = file
			g.Response.File = append(g.Response.File, file)
		}
	}

	if singlePackageMode {
		registry = ggdescriptor.NewRegistry()
		pgghelpers.SetRegistry(registry)
		if err = registry.Load(g.Request); err != nil {
			g.Error(err, "registry: failed to load the request")
		}
	}

	// Generate the encoders
	for _, file := range g.Request.GetProtoFile() {
		if all {
			if singlePackageMode {
				if _, err = registry.LookupFile(file.GetName()); err != nil {
					g.Error(err, "registry: failed to lookup file %q", file.GetName())
				}
			}
			encoder := NewGenericTemplateBasedEncoder(templateDir, file, debug, destinationDir)
			for _, tmpl := range encoder.Files() {
				concatOrAppend(tmpl)
			}

			continue
		}

		for _, service := range file.GetService() {
			encoder := NewGenericServiceTemplateBasedEncoder(templateDir, service, file, debug, destinationDir)
			for _, tmpl := range encoder.Files() {
				concatOrAppend(tmpl)
			}
		}
	}

	// Generate the protobufs
	g.GenerateAllFiles()

	data, err = proto.Marshal(g.Response)
	if err != nil {
		g.Error(err, "failed to marshal output proto")
	}

	_, err = os.Stdout.Write(data)
	if err != nil {
		g.Error(err, "failed to write output proto")
	}
}
<commit_msg>add parameter file-mode for template at file level (#143)<commit_after>package main // import "moul.io/protoc-gen-gotemplate"

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

	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/protoc-gen-go/generator"
	plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
	ggdescriptor "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"

	pgghelpers "moul.io/protoc-gen-gotemplate/helpers"
)

var (
	registry *ggdescriptor.Registry // some helpers need access to registry
)

const (
	boolTrue  = "true"
	boolFalse = "false"
)

func main() {
	g := generator.New()

	data, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		g.Error(err, "reading input")
	}

	if err = proto.Unmarshal(data, g.Request); err != nil {
		g.Error(err, "parsing input proto")
	}

	if len(g.Request.FileToGenerate) == 0 {
		g.Fail("no files to generate")
	}

	g.CommandLineParameters(g.Request.GetParameter())

	// Parse parameters
	var (
		templateDir       = "./templates"
		destinationDir    = "."
		debug             = false
		all               = false
		singlePackageMode = false
		fileMode          = false
	)
	if parameter := g.Request.GetParameter(); parameter != "" {
		for _, param := range strings.Split(parameter, ",") {
			parts := strings.Split(param, "=")
			if len(parts) != 2 {
				log.Printf("Err: invalid parameter: %q", param)
				continue
			}
			switch parts[0] {
			case "template_dir":
				templateDir = parts[1]
			case "destination_dir":
				destinationDir = parts[1]
			case "single-package-mode":
				switch strings.ToLower(parts[1]) {
				case boolTrue, "t":
					singlePackageMode = true
				case boolFalse, "f":
				default:
					log.Printf("Err: invalid value for single-package-mode: %q", parts[1])
				}
			case "debug":
				switch strings.ToLower(parts[1]) {
				case boolTrue, "t":
					debug = true
				case boolFalse, "f":
				default:
					log.Printf("Err: invalid value for debug: %q", parts[1])
				}
			case "all":
				switch strings.ToLower(parts[1]) {
				case boolTrue, "t":
					all = true
				case boolFalse, "f":
				default:
					log.Printf("Err: invalid value for debug: %q", parts[1])
				}
			case "file-mode":
				switch strings.ToLower(parts[1]) {
				case boolTrue, "t":
					fileMode = true
				case boolFalse, "f":
				default:
					log.Printf("Err: invalid value for file-mode: %q", parts[1])
				}
			default:
				log.Printf("Err: unknown parameter: %q", param)
			}
		}
	}

	tmplMap := make(map[string]*plugin_go.CodeGeneratorResponse_File)
	concatOrAppend := func(file *plugin_go.CodeGeneratorResponse_File) {
		if val, ok := tmplMap[file.GetName()]; ok {
			*val.Content += file.GetContent()
		} else {
			tmplMap[file.GetName()] = file
			g.Response.File = append(g.Response.File, file)
		}
	}

	if singlePackageMode {
		registry = ggdescriptor.NewRegistry()
		pgghelpers.SetRegistry(registry)
		if err = registry.Load(g.Request); err != nil {
			g.Error(err, "registry: failed to load the request")
		}
	}

	// Generate the encoders
	for _, file := range g.Request.GetProtoFile() {
		if all {
			if singlePackageMode {
				if _, err = registry.LookupFile(file.GetName()); err != nil {
					g.Error(err, "registry: failed to lookup file %q", file.GetName())
				}
			}
			encoder := NewGenericTemplateBasedEncoder(templateDir, file, debug, destinationDir)
			for _, tmpl := range encoder.Files() {
				concatOrAppend(tmpl)
			}

			continue
		}

		if fileMode {
			if s := file.GetService(); s != nil && len(s) > 0 {
				encoder := NewGenericTemplateBasedEncoder(templateDir, file, debug, destinationDir)
				for _, tmpl := range encoder.Files() {
					concatOrAppend(tmpl)
				}
			}

			continue
		}

		for _, service := range file.GetService() {
			encoder := NewGenericServiceTemplateBasedEncoder(templateDir, service, file, debug, destinationDir)
			for _, tmpl := range encoder.Files() {
				concatOrAppend(tmpl)
			}
		}
	}

	// Generate the protobufs
	g.GenerateAllFiles()

	data, err = proto.Marshal(g.Response)
	if err != nil {
		g.Error(err, "failed to marshal output proto")
	}

	_, err = os.Stdout.Write(data)
	if err != nil {
		g.Error(err, "failed to write output proto")
	}
}
<|endoftext|>


<commit_before>package main

import "github.com/gin-gonic/gin"
import "github.com/evnix/boltdb-browser/web"

import ("fmt"
		log "github.com/Sirupsen/logrus"
		 "github.com/boltdb/bolt"
		 "os")

var db *bolt.DB

func main() {

	fmt.Print(" ")
	log.Info("starting boltdb-browser...")

	if(len(os.Args)<2){

		fmt.Println("Usage: "+os.Args[0]+" <DBfilename>[required] <port>[optional]")
		os.Exit(0)
	}

	var err error
	db,err=bolt.Open(os.Args[1], 0600, nil)
	boltbrowserweb.Db=db

	if(err!=nil){

		fmt.Println(err)
		os.Exit(0)
	}

	r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })

    r.GET("/", boltbrowserweb.Index)

    r.GET("/buckets", boltbrowserweb.Buckets)
    r.POST("/createBucket", boltbrowserweb.CreateBucket)
    r.POST("/put", boltbrowserweb.Put)
    r.POST("/get", boltbrowserweb.Get)
    r.POST("/deleteKey", boltbrowserweb.DeleteKey)
    r.POST("/deleteBucket", boltbrowserweb.DeleteBucket)
    r.POST("/prefixScan", boltbrowserweb.PrefixScan)

    r.Static("/web", "./web")

    port:="8080";

    if(len(os.Args)>2){

    	port=os.Args[2]
    }

    r.Run(":"+port)

}<commit_msg>renamed pkg<commit_after>package main

import "github.com/gin-gonic/gin"
import "github.com/evnix/boltdbweb/web"

import ("fmt"
		log "github.com/Sirupsen/logrus"
		 "github.com/boltdb/bolt"
		 "os")

var db *bolt.DB

func main() {

	fmt.Print(" ")
	log.Info("starting boltdb-browser...")

	if(len(os.Args)<2){

		fmt.Println("Usage: "+os.Args[0]+" <DBfilename>[required] <port>[optional]")
		os.Exit(0)
	}

	var err error
	db,err=bolt.Open(os.Args[1], 0600, nil)
	boltbrowserweb.Db=db

	if(err!=nil){

		fmt.Println(err)
		os.Exit(0)
	}

	r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })

    r.GET("/", boltbrowserweb.Index)

    r.GET("/buckets", boltbrowserweb.Buckets)
    r.POST("/createBucket", boltbrowserweb.CreateBucket)
    r.POST("/put", boltbrowserweb.Put)
    r.POST("/get", boltbrowserweb.Get)
    r.POST("/deleteKey", boltbrowserweb.DeleteKey)
    r.POST("/deleteBucket", boltbrowserweb.DeleteBucket)
    r.POST("/prefixScan", boltbrowserweb.PrefixScan)

    r.Static("/web", "./web")

    port:="8080";

    if(len(os.Args)>2){

    	port=os.Args[2]
    }

    r.Run(":"+port)

}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

var inputFilename string
var author string
var title string

func mainExitCode() int {
	flag.StringVar(&inputFilename, "f", "", "Input filename")
	flag.StringVar(&author, "a", "", "Author. Can be empty")
	flag.StringVar(&title, "t", "", "Title. Can be empty")
	flag.Parse()
	if inputFilename == "" {
		fmt.Println("Input Filename can't be empty, print --help for usage")
		return 1
	}
	data, err := ioutil.ReadFile(inputFilename) // For read access.
	if err != nil {
		fmt.Println(err)
		return 1
	}
	if author != "" && title != "" {
		fmt.Println(title)
		fmt.Println(author)
	}
	fmt.Println(strings.TrimLeft(RemoveHTMLTags(RubyToBunko(AddNewline(string(data)))), "\r\n \t"))
	return 0
}

func main() {
	os.Exit(mainExitCode())
}
<commit_msg>Adds newline after author/title. New default vals for title and author<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

var inputFilename string
var author string
var title string

func mainExitCode() int {
	flag.StringVar(&inputFilename, "f", "", "Input filename")
	flag.StringVar(&author, "a", "Unknown author", "Author. Can be empty")
	flag.StringVar(&title, "t", "Unknown title", "Title. Can be empty")
	flag.Parse()
	if inputFilename == "" {
		fmt.Println("Input Filename can't be empty, print --help for usage")
		return 1
	}
	data, err := ioutil.ReadFile(inputFilename) // For read access.
	if err != nil {
		fmt.Println(err)
		return 1
	}
	if author != "" && title != "" {
		fmt.Println(title)
		fmt.Println(author)
		fmt.Println("")
	}
	fmt.Println(strings.TrimLeft(RemoveHTMLTags(RubyToBunko(AddNewline(string(data)))), "\r\n \t"))
	return 0
}

func main() {
	os.Exit(mainExitCode())
}
<|endoftext|>


<commit_before>// govcl project main.go
// go.exe build -i -ldflags="-H windowsgui"
package main

import (
	"fmt"

	"github.com/ying32/govcl/vcl"
	"github.com/ying32/govcl/vcl/exts/tools"
	"github.com/ying32/govcl/vcl/rtl"
	"github.com/ying32/govcl/vcl/rtl/version"
	"github.com/ying32/govcl/vcl/types"
	"github.com/ying32/govcl/vcl/win"
)

var (
	mainForm *vcl.TForm
	trayicon *vcl.TTrayIcon
)

func main() {

	// mac下记得发布时去掉
	tools.RunWithMacOSApp()
	// 异常捕获
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("Exception: ", err)
			vcl.ShowMessage(err.(error).Error())
		}
	}()

	fmt.Println("main")
	vcl.Application.SetIconResId(3)
	vcl.Application.Initialize()

	vcl.Application.SetOnException(func(sender vcl.IObject, e *vcl.Exception) {
		fmt.Println("exception.")
	})

	vcl.Application.SetTitle("Hello World! 系统信息：" + version.OSVersion.ToString())
	vcl.Application.SetMainFormOnTaskBar(true)
	// 窗口自动根据系统绽放，默认为true
	//vcl.Application.SetFormScaled(false)

	mainForm = vcl.Application.CreateForm()
	mainForm.SetWidth(800)
	mainForm.SetHeight(600)
	mainForm.SetOnClose(func(Sender vcl.IObject, Action *types.TCloseAction) {
		fmt.Println("close")
	})

	// 窗口大小约束
	mainForm.SetOnConstrainedResize(func(sender vcl.IObject, minWidth, minHeight, maxWidth, maxHeight *int32) {
		*minWidth = 800
		*minHeight = 600
		*maxWidth = 800
		*maxHeight = 600
	})

	mainForm.SetOnDestroy(func(sender vcl.IObject) {
		fmt.Println("Form Destroy.")
	})

	fmt.Println("MainForm ClientRect: ", mainForm.ClientRect())
	filename := vcl.Application.ExeName()
	fmt.Println("application.ExeName: ", filename)
	fmt.Println("path: ", rtl.ExtractFilePath(filename))
	fmt.Println("fileExists: ", rtl.FileExists(filename))

	mainForm.SetOnCloseQuery(func(Sender vcl.IObject, CanClose *bool) {
		*CanClose = vcl.MessageDlg("是否退出?", types.MtInformation, types.MbYes, types.MbNo) == types.MrYes
		fmt.Println("OnCloseQuery")
	})

	mainForm.SetCaption(vcl.Application.Title())
	mainForm.EnabledMaximize(false)
	mainForm.SetDoubleBuffered(true)
	//mainForm.SetPosition(types.PoScreenCenter)
	//mainForm.ScreenCenter()
	mainForm.WorkAreaCenter()
	mainForm.SetKeyPreview(true)
	mainForm.SetOnKeyDown(func(Sender vcl.IObject, Key *types.Char, Shift types.TShiftState) {
		fmt.Println(rtl.InSets(uint32(Shift), types.SsCtrl))
		fmt.Println("key:", *Key)
	})

	mainForm.SetOnMouseDown(func(sender vcl.IObject, button types.TMouseButton, shift types.TShiftState, x, y int32) {
		fmt.Println("Button:", button == types.MbLeft, ", X:", x, ", y:", y)
		fmt.Println("OnMouseDown")
	})

	chk := vcl.NewCheckBox(mainForm)
	chk.SetParent(mainForm)
	chk.SetChecked(true)
	chk.SetCaption("测试")
	chk.SetLeft(1)
	chk.SetTop(60)
	chk.SetOnClick(func(vcl.IObject) {
		fmt.Println("chk.Checked=", chk.Checked())
	})

	// action
	action := vcl.NewAction(mainForm)
	action.SetCaption("action1")
	action.SetOnUpdate(func(sender vcl.IObject) {
		vcl.ActionFromObj(sender).SetEnabled(chk.Checked())
	})
	action.SetOnExecute(func(vcl.IObject) {
		fmt.Println("action execute")
	})
	btn := vcl.NewButton(mainForm)
	btn.SetParent(mainForm)
	btn.SetBounds(250, 30, 90, 25)
	btn.SetCaption("action")
	btn.SetAction(action)

	trayicon = vcl.NewTrayIcon(mainForm)
	if rtl.LcLLoaded() {
		trayicon.SetIcon(vcl.Application.Icon()) //不设置会自动使用Application.Icon
	}

	trayicon.SetHint(mainForm.Caption())
	trayicon.SetVisible(true)
	trayicon.SetOnClick(func(vcl.IObject) {
		trayicon.SetBalloonTitle("test")
		trayicon.SetBalloonTimeout(10000)
		trayicon.SetBalloonHint("我是提示正文啦")
		trayicon.ShowBalloonHint()
		fmt.Println("TrayIcon Click.")
	})

	// img
	img := vcl.NewImage(mainForm)
	img.SetBounds(132, 30, 156, 97)
	img.SetParent(mainForm)
	img.Picture().LoadFromFile("./imgs/1.jpg")
	//img.SetStretch(true)
	img.SetProportional(true)

	// linklabel
	linklbl := vcl.NewLinkLabel(mainForm)
	linklbl.SetAlign(types.AlBottom)
	linklbl.SetCaption("govcl测试链接")
	linklbl.SetParent(mainForm)
	linklbl.SetOnLinkClick(func(sender vcl.IObject, link string, linktype types.TSysLinkType) {
		fmt.Println("link label: ", link, ", type: ", linktype)
		rtl.SysOpen(link)
	})

	// menu
	mainMenu := vcl.NewMainMenu(mainForm)
	item := vcl.NewMenuItem(mainForm)
	item.SetCaption("File(&F)")
	mainMenu.Items().Add(item)

	item2 := vcl.NewMenuItem(mainForm)
	item2.SetCaption("MemoryStreamTest")
	item2.SetOnClick(func(vcl.IObject) {
		mem := vcl.NewMemoryStream()
		defer mem.Free()
		mem.Write([]byte("测试"))
		mem.SaveToFile("test.txt")

		mem.SetPosition(0)
		n, bs := mem.Read(int32(mem.Size()))
		fmt.Println("n:", n, ", bs:", bs, ", str:", string(bs))
	})
	item.Add(item2)

	item2 = vcl.NewMenuItem(mainForm)
	item2.SetCaption("Exit(&E)")
	item2.SetShortCutFromString("Ctrl+Q")
	item2.SetOnClick(func(vcl.IObject) {
		mainForm.Close()
	})
	item.Add(item2)

	//	mainForm.EnabledMinimize(false)
	//	mainForm.EnabledSystemMenu(false)

	button := vcl.NewButton(mainForm)

	button.SetCaption("消息")
	button.SetParent(mainForm)
	button.SetOnClick(func(vcl.IObject) {
		fmt.Println("button click")
		vcl.ShowMessage("这是一个消息")
		vcl.Application.MessageBox("Hello!", "Message", win.MB_YESNO+win.MB_ICONINFORMATION)
	})
	button.SetLeft(50)
	button.SetTop(50)
	button.SetAlign(types.AlRight)

	edit := vcl.NewEdit(mainForm)
	edit.SetParent(mainForm)
	edit.SetLeft(1)
	edit.SetTop(30)
	edit.SetTextHint("测试")
	edit.SetOnChange(func(vcl.IObject) {
		fmt.Println("edit OnChange")
	})

	button2 := vcl.NewButton(mainForm)
	button2.SetParent(mainForm)
	button2.SetCaption("a")
	button2.SetWidth(100)
	button2.SetHeight(28)
	button2.SetOnClick(func(vcl.IObject) {
		fmt.Println("button2 click")

		edit.SetText("Hello!")
		fmt.Println("ScreenWidth:", vcl.Screen.Width(), ", ScreenHeight:", vcl.Screen.Height())
	})
	button2.SetAlign(types.AlTop)

	combo := vcl.NewComboBox(mainForm)
	combo.SetAlign(types.AlBottom)
	combo.SetParent(mainForm)
	combo.SetText("ffff")
	combo.Items().Add("1")
	combo.Items().Add("2")
	combo.SetItemIndex(0)
	combo.SetOnChange(func(vcl.IObject) {
		if combo.ItemIndex() != -1 {
			fmt.Println("combo Change: ", combo.Items().Strings(combo.ItemIndex()))
		}

	})

	page := vcl.NewPageControl(mainForm)
	page.SetParent(mainForm)
	page.SetAlign(types.AlBottom)
	sheet := vcl.NewTabSheet(mainForm)
	sheet.SetPageControl(page)
	sheet.SetCaption("第一页")

	// 需要先将TabSheet设置了父窗口，TListView才可用，不然就会报错
	lv1 := vcl.NewListView(mainForm)
	lv1.SetAlign(types.AlClient)
	lv1.SetParent(sheet)

	lv1.SetViewStyle(types.VsReport)
	lv1.SetRowSelect(true)
	lv1.SetReadOnly(true)
	lv1.SetGridLines(true)
	col := lv1.Columns().Add()
	col.SetCaption("序号")
	col.SetWidth(100)
	// 强制柱头宽，即使被调整也会被还原
	col.SetMaxWidth(100)
	col.SetMinWidth(100)
	col = lv1.Columns().Add()
	col.SetCaption("名称")
	col.SetWidth(200)
	col = lv1.Columns().Add()
	col.SetCaption("内容")
	col.SetWidth(200)
	lv1.SetOnClick(func(vcl.IObject) {
		if lv1.ItemIndex() != -1 {
			item := lv1.Selected() // lv1.Items().Item(lv1.ItemIndex())
			fmt.Println(item.Caption(),
				item.SubItems().Strings(0),
				item.SubItems().Strings(1))
		}
	})

	lv1.Items().BeginUpdate()
	for i := 1; i <= 50; i++ {
		lstitem := lv1.Items().Add()
		lstitem.SetCaption(fmt.Sprintf("%d", i))
		lstitem.SubItems().Add(fmt.Sprintf("第%d", i))
		lstitem.SubItems().Add(fmt.Sprintf("内容%d", i))
	}
	lv1.Items().EndUpdate()

	sheet = vcl.NewTabSheet(mainForm)
	sheet.SetCaption("第二页")
	sheet.SetPageControl(page)

	// -----------TreeView 不同Node弹出不同菜单，两个右键例程不同使用

	tvpm1 := vcl.NewPopupMenu(mainForm)
	mItem := vcl.NewMenuItem(mainForm)
	mItem.SetCaption("第一种")
	tvpm1.Items().Add(mItem)

	tvpm2 := vcl.NewPopupMenu(mainForm)
	mItem = vcl.NewMenuItem(mainForm)
	mItem.SetCaption("第二种")
	tvpm2.Items().Add(mItem)

	tv1 := vcl.NewTreeView(mainForm)
	tv1.SetAutoExpand(true)
	tv1.SetParent(sheet)
	tv1.SetAlign(types.AlClient)
	//	tv1.SetRightClickSelect(true)
	tv1.SetOnClick(func(vcl.IObject) {
		if tv1.SelectionCount() > 0 {
			node := tv1.Selected()
			fmt.Println("text:", node.Text(), ", index:", node.Index())
		}
	})

	tv1.SetOnMouseDown(func(sender vcl.IObject, button types.TMouseButton, shift types.TShiftState, x, y int32) {
		if button == types.MbRight {
			node := tv1.GetNodeAt(x, y)
			if node != nil && node.IsValid() {
				// 自由决择是否选中
				node.SetSelected(true)
				// 根据Level来判断，这里只是做演示
				p := vcl.Mouse.CursorPos()
				switch node.Level() {
				case 0:
					tvpm1.Popup(p.X, p.Y)
				case 1:
					tvpm2.Popup(p.X, p.Y)
				}
				fmt.Println("node.Level():", node.Level(), ", text:", node.Text())
			}
		}
	})

	tv1.Items().BeginUpdate()
	node := tv1.Items().AddChild(nil, "首个")
	for i := 1; i <= 50; i++ {
		tv1.Items().AddChild(node, fmt.Sprintf("Node%d", i))
	}
	node = tv1.Items().AddChild(nil, "第二个")
	for i := 1; i <= 50; i++ {
		tv1.Items().AddChild(node, fmt.Sprintf("Node%d", i))
	}
	tv1.Items().EndUpdate()

	fmt.Println("Compoment Count:", mainForm.ComponentCount())
	//	mainForm.ScreenCenter()

	lbl := vcl.NewLabel(mainForm)
	lbl.SetCaption("标签")
	lbl.SetAlign(types.AlBottom)
	fmt.Println("InheritsFromControl:", rtl.InheritsFromControl(mainForm.Instance()))
	fmt.Println("InheritsFromWinControl:", rtl.InheritsFromWinControl(mainForm.Instance()))
	fmt.Println("InheritsFromComponent:", rtl.InheritsFromComponent(tv1.Instance()))
	fmt.Println("InheritsFromWinControl:", rtl.InheritsFromWinControl(lbl.Instance()))

	vcl.Application.Run()
}
<commit_msg>更新govcl例程，测试新添加的方法<commit_after>// govcl project main.go
// go.exe build -i -ldflags="-H windowsgui"
package main

import (
	"fmt"

	"github.com/ying32/govcl/vcl"
	"github.com/ying32/govcl/vcl/exts/tools"
	"github.com/ying32/govcl/vcl/rtl"
	"github.com/ying32/govcl/vcl/rtl/version"
	"github.com/ying32/govcl/vcl/types"
	"github.com/ying32/govcl/vcl/win"
)

var (
	mainForm *vcl.TForm
	trayicon *vcl.TTrayIcon
)

func main() {

	// mac下记得发布时去掉
	tools.RunWithMacOSApp()
	// 异常捕获
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("Exception: ", err)
			vcl.ShowMessage(err.(error).Error())
		}
	}()

	fmt.Println("InheritsFrom：", vcl.Application.InheritsFrom(vcl.TObjectClass()))
	fmt.Println("InheritsFrom：", vcl.Application.InheritsFrom(vcl.TComponentClass()))
	fmt.Println("InheritsFrom：", vcl.Application.InheritsFrom(vcl.TControlClass()))

	fmt.Println("main")
	vcl.Application.SetIconResId(3)
	vcl.Application.Initialize()

	vcl.Application.SetOnException(func(sender vcl.IObject, e *vcl.Exception) {
		fmt.Println("exception.")
	})

	vcl.Application.SetTitle("Hello World! 系统信息：" + version.OSVersion.ToString())
	vcl.Application.SetMainFormOnTaskBar(true)
	// 窗口自动根据系统绽放，默认为true
	//vcl.Application.SetFormScaled(false)

	mainForm = vcl.Application.CreateForm()
	mainForm.SetWidth(800)
	mainForm.SetHeight(600)
	mainForm.SetOnClose(func(Sender vcl.IObject, Action *types.TCloseAction) {
		fmt.Println("close")
	})

	// 窗口大小约束
	mainForm.SetOnConstrainedResize(func(sender vcl.IObject, minWidth, minHeight, maxWidth, maxHeight *int32) {
		*minWidth = 800
		*minHeight = 600
		*maxWidth = 800
		*maxHeight = 600
	})

	mainForm.SetOnDestroy(func(sender vcl.IObject) {
		fmt.Println("Form Destroy.")
	})

	fmt.Println("MainForm ClientRect: ", mainForm.ClientRect())
	filename := vcl.Application.ExeName()
	fmt.Println("application.ExeName: ", filename)
	fmt.Println("path: ", rtl.ExtractFilePath(filename))
	fmt.Println("fileExists: ", rtl.FileExists(filename))

	mainForm.SetOnCloseQuery(func(Sender vcl.IObject, CanClose *bool) {
		*CanClose = vcl.MessageDlg("是否退出?", types.MtInformation, types.MbYes, types.MbNo) == types.MrYes
		fmt.Println("OnCloseQuery")
	})

	mainForm.SetCaption(vcl.Application.Title())
	mainForm.EnabledMaximize(false)
	mainForm.SetDoubleBuffered(true)
	//mainForm.SetPosition(types.PoScreenCenter)
	//mainForm.ScreenCenter()
	mainForm.WorkAreaCenter()
	mainForm.SetKeyPreview(true)
	mainForm.SetOnKeyDown(func(Sender vcl.IObject, Key *types.Char, Shift types.TShiftState) {
		fmt.Println(rtl.InSets(uint32(Shift), types.SsCtrl))
		fmt.Println("key:", *Key)
	})

	mainForm.SetOnMouseDown(func(sender vcl.IObject, button types.TMouseButton, shift types.TShiftState, x, y int32) {
		fmt.Println("Button:", button == types.MbLeft, ", X:", x, ", y:", y)
		fmt.Println("OnMouseDown")
	})

	chk := vcl.NewCheckBox(mainForm)
	chk.SetParent(mainForm)
	chk.SetChecked(true)
	chk.SetCaption("测试")
	chk.SetLeft(1)
	chk.SetTop(60)
	chk.SetOnClick(func(vcl.IObject) {
		fmt.Println("chk.Checked=", chk.Checked())
	})

	// action
	action := vcl.NewAction(mainForm)
	action.SetCaption("action1")
	action.SetOnUpdate(func(sender vcl.IObject) {
		vcl.ActionFromObj(sender).SetEnabled(chk.Checked())
	})
	action.SetOnExecute(func(vcl.IObject) {
		fmt.Println("action execute")
	})
	btn := vcl.NewButton(mainForm)
	btn.SetParent(mainForm)
	btn.SetBounds(250, 30, 90, 25)
	btn.SetCaption("action")
	btn.SetAction(action)

	trayicon = vcl.NewTrayIcon(mainForm)
	if rtl.LcLLoaded() {
		trayicon.SetIcon(vcl.Application.Icon()) //不设置会自动使用Application.Icon
	}

	trayicon.SetHint(mainForm.Caption())
	trayicon.SetVisible(true)
	trayicon.SetOnClick(func(vcl.IObject) {
		trayicon.SetBalloonTitle("test")
		trayicon.SetBalloonTimeout(10000)
		trayicon.SetBalloonHint("我是提示正文啦")
		trayicon.ShowBalloonHint()
		fmt.Println("TrayIcon Click.")
	})

	// img
	img := vcl.NewImage(mainForm)
	img.SetBounds(132, 30, 156, 97)
	img.SetParent(mainForm)
	img.Picture().LoadFromFile("./imgs/1.jpg")
	//img.SetStretch(true)
	img.SetProportional(true)

	// linklabel
	linklbl := vcl.NewLinkLabel(mainForm)
	linklbl.SetAlign(types.AlBottom)
	linklbl.SetCaption("govcl测试链接")
	linklbl.SetParent(mainForm)
	linklbl.SetOnLinkClick(func(sender vcl.IObject, link string, linktype types.TSysLinkType) {
		fmt.Println("link label: ", link, ", type: ", linktype)
		rtl.SysOpen(link)
	})

	// menu
	mainMenu := vcl.NewMainMenu(mainForm)
	item := vcl.NewMenuItem(mainForm)
	item.SetCaption("File(&F)")
	mainMenu.Items().Add(item)

	item2 := vcl.NewMenuItem(mainForm)
	item2.SetCaption("MemoryStreamTest")
	item2.SetOnClick(func(vcl.IObject) {
		mem := vcl.NewMemoryStream()
		defer mem.Free()
		mem.Write([]byte("测试"))
		mem.SaveToFile("test.txt")

		mem.SetPosition(0)
		n, bs := mem.Read(int32(mem.Size()))
		fmt.Println("n:", n, ", bs:", bs, ", str:", string(bs))
	})
	item.Add(item2)

	item2 = vcl.NewMenuItem(mainForm)
	item2.SetCaption("Exit(&E)")
	item2.SetShortCutFromString("Ctrl+Q")
	item2.SetOnClick(func(vcl.IObject) {
		mainForm.Close()
	})
	item.Add(item2)

	//	mainForm.EnabledMinimize(false)
	//	mainForm.EnabledSystemMenu(false)

	button := vcl.NewButton(mainForm)

	button.SetCaption("消息")
	button.SetParent(mainForm)
	button.SetOnClick(func(vcl.IObject) {
		fmt.Println("button click")
		vcl.ShowMessage("这是一个消息")
		vcl.Application.MessageBox("Hello!", "Message", win.MB_YESNO+win.MB_ICONINFORMATION)
	})
	button.SetLeft(50)
	button.SetTop(50)
	button.SetAlign(types.AlRight)

	edit := vcl.NewEdit(mainForm)
	edit.SetParent(mainForm)
	edit.SetLeft(1)
	edit.SetTop(30)
	edit.SetTextHint("测试")
	edit.SetOnChange(func(vcl.IObject) {
		fmt.Println("edit OnChange")
	})

	button2 := vcl.NewButton(mainForm)
	button2.SetParent(mainForm)
	button2.SetCaption("a")
	button2.SetWidth(100)
	button2.SetHeight(28)
	button2.SetOnClick(func(vcl.IObject) {
		fmt.Println("button2 click")

		edit.SetText("Hello!")
		fmt.Println("ScreenWidth:", vcl.Screen.Width(), ", ScreenHeight:", vcl.Screen.Height())
	})
	button2.SetAlign(types.AlTop)

	combo := vcl.NewComboBox(mainForm)
	combo.SetAlign(types.AlBottom)
	combo.SetParent(mainForm)
	combo.SetText("ffff")
	combo.Items().Add("1")
	combo.Items().Add("2")
	combo.SetItemIndex(0)
	combo.SetOnChange(func(vcl.IObject) {
		if combo.ItemIndex() != -1 {
			fmt.Println("combo Change: ", combo.Items().Strings(combo.ItemIndex()))
		}

	})

	page := vcl.NewPageControl(mainForm)
	page.SetParent(mainForm)
	page.SetAlign(types.AlBottom)
	sheet := vcl.NewTabSheet(mainForm)
	sheet.SetPageControl(page)
	sheet.SetCaption("第一页")

	// 需要先将TabSheet设置了父窗口，TListView才可用，不然就会报错
	lv1 := vcl.NewListView(mainForm)
	lv1.SetAlign(types.AlClient)
	lv1.SetParent(sheet)

	lv1.SetViewStyle(types.VsReport)
	lv1.SetRowSelect(true)
	lv1.SetReadOnly(true)
	lv1.SetGridLines(true)
	col := lv1.Columns().Add()
	col.SetCaption("序号")
	col.SetWidth(100)
	// 强制柱头宽，即使被调整也会被还原
	col.SetMaxWidth(100)
	col.SetMinWidth(100)
	col = lv1.Columns().Add()
	col.SetCaption("名称")
	col.SetWidth(200)
	col = lv1.Columns().Add()
	col.SetCaption("内容")
	col.SetWidth(200)
	lv1.SetOnClick(func(vcl.IObject) {
		if lv1.ItemIndex() != -1 {
			item := lv1.Selected() // lv1.Items().Item(lv1.ItemIndex())
			fmt.Println(item.Caption(),
				item.SubItems().Strings(0),
				item.SubItems().Strings(1))
		}
	})

	lv1.Items().BeginUpdate()
	for i := 1; i <= 50; i++ {
		lstitem := lv1.Items().Add()
		lstitem.SetCaption(fmt.Sprintf("%d", i))
		lstitem.SubItems().Add(fmt.Sprintf("第%d", i))
		lstitem.SubItems().Add(fmt.Sprintf("内容%d", i))
	}
	lv1.Items().EndUpdate()

	sheet = vcl.NewTabSheet(mainForm)
	sheet.SetCaption("第二页")
	sheet.SetPageControl(page)

	// -----------TreeView 不同Node弹出不同菜单，两个右键例程不同使用

	tvpm1 := vcl.NewPopupMenu(mainForm)
	mItem := vcl.NewMenuItem(mainForm)
	mItem.SetCaption("第一种")
	tvpm1.Items().Add(mItem)

	tvpm2 := vcl.NewPopupMenu(mainForm)
	mItem = vcl.NewMenuItem(mainForm)
	mItem.SetCaption("第二种")
	tvpm2.Items().Add(mItem)

	tv1 := vcl.NewTreeView(mainForm)
	tv1.SetAutoExpand(true)
	tv1.SetParent(sheet)
	tv1.SetAlign(types.AlClient)
	//	tv1.SetRightClickSelect(true)
	tv1.SetOnClick(func(vcl.IObject) {
		if tv1.SelectionCount() > 0 {
			node := tv1.Selected()
			fmt.Println("text:", node.Text(), ", index:", node.Index())
		}
	})

	tv1.SetOnMouseDown(func(sender vcl.IObject, button types.TMouseButton, shift types.TShiftState, x, y int32) {
		if button == types.MbRight {
			node := tv1.GetNodeAt(x, y)
			if node != nil && node.IsValid() {
				// 自由决择是否选中
				node.SetSelected(true)
				// 根据Level来判断，这里只是做演示
				p := vcl.Mouse.CursorPos()
				switch node.Level() {
				case 0:
					tvpm1.Popup(p.X, p.Y)
				case 1:
					tvpm2.Popup(p.X, p.Y)
				}
				fmt.Println("node.Level():", node.Level(), ", text:", node.Text())
			}
		}
	})

	tv1.Items().BeginUpdate()
	node := tv1.Items().AddChild(nil, "首个")
	for i := 1; i <= 50; i++ {
		tv1.Items().AddChild(node, fmt.Sprintf("Node%d", i))
	}
	node = tv1.Items().AddChild(nil, "第二个")
	for i := 1; i <= 50; i++ {
		tv1.Items().AddChild(node, fmt.Sprintf("Node%d", i))
	}
	tv1.Items().EndUpdate()

	fmt.Println("Compoment Count:", mainForm.ComponentCount())
	//	mainForm.ScreenCenter()

	lbl := vcl.NewLabel(mainForm)
	lbl.SetCaption("标签")
	lbl.SetAlign(types.AlBottom)
	fmt.Println("InheritsFromControl:", rtl.InheritsFromControl(mainForm.Instance()))
	fmt.Println("InheritsFromWinControl:", rtl.InheritsFromWinControl(mainForm.Instance()))
	fmt.Println("InheritsFromComponent:", rtl.InheritsFromComponent(tv1.Instance()))
	fmt.Println("InheritsFromWinControl:", rtl.InheritsFromWinControl(lbl.Instance()))

	vcl.Application.Run()
}
<|endoftext|>


<commit_before>package main

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

	"github.com/Sirupsen/logrus"
	"github.com/anthonynsimon/parrot/api"
	"github.com/anthonynsimon/parrot/auth"
	"github.com/anthonynsimon/parrot/datastore"
	"github.com/anthonynsimon/parrot/logger"
	"github.com/joho/godotenv"
	"github.com/pressly/chi"
	"github.com/pressly/chi/middleware"
)

func init() {
	// Config log
	logrus.SetOutput(os.Stdout)
	logrus.SetFormatter(&logrus.TextFormatter{})
	logrus.SetLevel(logrus.InfoLevel)
}

func main() {
	// init environment variables
	err := godotenv.Load()
	if err != nil {
		logrus.Fatal(err)
	}

	// init and ping datastore
	dbName := os.Getenv("DB")
	dbURL := os.Getenv("DB_URL")

	ds, err := datastore.NewDatastore(dbName, dbURL)
	if err != nil {
		logrus.Fatal(err)
	}

	defer ds.Close()
	if err = ds.Ping(); err != nil {
		logrus.Fatal(fmt.Sprintf("failed to ping datastore.\nerr: %s", err))
	}

	// init routers and middleware
	mainRouter := chi.NewRouter()
	mainRouter.Use(
		logger.Request,
		middleware.StripSlashes,
	)

	ap := auth.Provider{
		Name:       string([]byte(os.Getenv("DOMAIN"))),
		SigningKey: []byte(os.Getenv("API_SIGNING_KEY"))}

	apiRouter := api.NewRouter(ds, ap)
	mainRouter.Mount("/api", apiRouter)

	// config server
	addr := "localhost:8080"

	// init server
	s := &http.Server{
		Addr:           addr,
		Handler:        mainRouter,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	logrus.Info(fmt.Sprintf("Listening on %s", addr))

	logrus.Fatal(s.ListenAndServe())
}
<commit_msg>Add comment<commit_after>package main

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

	"github.com/Sirupsen/logrus"
	"github.com/anthonynsimon/parrot/api"
	"github.com/anthonynsimon/parrot/auth"
	"github.com/anthonynsimon/parrot/datastore"
	"github.com/anthonynsimon/parrot/logger"
	"github.com/joho/godotenv"
	"github.com/pressly/chi"
	"github.com/pressly/chi/middleware"
)

func init() {
	// Config log
	logrus.SetOutput(os.Stdout)
	logrus.SetFormatter(&logrus.TextFormatter{})
	logrus.SetLevel(logrus.InfoLevel)
}

func main() {
	// init environment variables
	err := godotenv.Load()
	if err != nil {
		logrus.Fatal(err)
	}

	// init and ping datastore
	dbName := os.Getenv("DB")
	dbURL := os.Getenv("DB_URL")

	ds, err := datastore.NewDatastore(dbName, dbURL)
	if err != nil {
		logrus.Fatal(err)
	}

	defer ds.Close()
	if err = ds.Ping(); err != nil {
		logrus.Fatal(fmt.Sprintf("failed to ping datastore.\nerr: %s", err))
	}

	// init routers and middleware
	// CORS, Rate-limiting, etc... is handled in nginx
	// Here we only care about application level middleware
	mainRouter := chi.NewRouter()
	mainRouter.Use(
		logger.Request,
		middleware.StripSlashes,
	)

	ap := auth.Provider{
		Name:       string([]byte(os.Getenv("DOMAIN"))),
		SigningKey: []byte(os.Getenv("API_SIGNING_KEY"))}

	apiRouter := api.NewRouter(ds, ap)
	mainRouter.Mount("/api", apiRouter)

	// config server
	addr := "localhost:8080"

	// init server
	s := &http.Server{
		Addr:           addr,
		Handler:        mainRouter,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	logrus.Info(fmt.Sprintf("Listening on %s", addr))

	logrus.Fatal(s.ListenAndServe())
}
<|endoftext|>


<commit_before>package main

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

	"github.com/codegangsta/cli"
)

type CodeFile struct {
	filename  string
	extension string
	name      string
	ftype     string
}

func newCodeFile(filename string) CodeFile {
	var f CodeFile

	f.filename = filename
	f.extension = filepath.Ext(filename)
	f.name = filename[0 : len(filename)-len(f.extension)]

	if f.extension != "" {
		f.ftype = f.extension[1:]
	}
	return f
}

func (f *CodeFile) show() {
	fmt.Printf("[Filename]: %s\n[Name]: %s\n[Extension]: %s\n[Type]: %s\n",
		f.filename, f.name, f.extension, f.ftype)
}

func (f *CodeFile) Compile() error {
	// (TODO): Support different filetype
	// (TODO): Check operating system

	cmd := exec.Command("gcc", "-o", f.name, f.filename)
	cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr

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

func (f *CodeFile) Run() error {
	var cmd *exec.Cmd

	switch f.ftype {
	case "":
		cmd = exec.Command("./", f.name)
	case "c":
		f.Compile()
		cmd = exec.Command("./" + f.name)
	case "go":
		cmd = exec.Command("go", "run", f.filename)
	case "py":
		// (TODO): different python versions
		cmd = exec.Command("python", f.filename)
	case "lua":
		cmd = exec.Command("lua", f.filename)
	case "ruby":
		cmd = exec.Command("ruby", f.filename)

	default:
		return errors.New("Not a valid filetype!\n[Supported] bin, C" +
			"Go, Python, Lua, Ruby")
	}
	cmd.Stdout, cmd.Stderr, cmd.Stdin = os.Stdout, os.Stderr, os.Stdin

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

func compile(c *cli.Context) {
	file := newCodeFile(c.Args().First())

	if err := file.Compile(); err != nil {
		fmt.Errorf("%v\n", err)
	}
}

func run(c *cli.Context) {
	file := newCodeFile(c.Args().First())

	if err := file.Run(); err != nil {
		fmt.Errorf("%v\n", err)
	}
}

func main() {
	app := cli.NewApp()
	app.Usage = "Compile and/or run your code files"
	app.Commands = []cli.Command{
		{
			Name:      "compile",
			ShortName: "c",
			Usage:     "compiles a file",
			Action:    compile,
		},
		{
			Name:   "run",
			Usage:  "Run a file/script, it compiles it if needed",
			Action: run,
		},
	}
	app.RunAndExitOnError()
}
<commit_msg>Removed cli package<commit_after>package main

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

type CodeFile struct {
	filename  string
	extension string
	name      string
	ftype     string
}

func newCodeFile(filename string) CodeFile {
	var f CodeFile

	f.filename = filename
	f.extension = filepath.Ext(filename)
	f.name = filename[0 : len(filename)-len(f.extension)]

	if f.extension != "" {
		f.ftype = f.extension[1:]
	}
	return f
}

func (f *CodeFile) show() {
	fmt.Printf("[Filename]: %s\n[Name]: %s\n[Extension]: %s\n[Type]: %s\n",
		f.filename, f.name, f.extension, f.ftype)
}

func (f *CodeFile) Compile() error {
	// (TODO): Support different filetype
	// (TODO): Check operating system

	cmd := exec.Command("gcc", "-o", f.name, f.filename)
	cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr

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

func (f *CodeFile) Run() error {
	var cmd *exec.Cmd

	switch f.ftype {
	case "":
		cmd = exec.Command("./", f.name)
	case "c":
		f.Compile()
		cmd = exec.Command("./" + f.name)
	case "go":
		cmd = exec.Command("go", "run", f.filename)
	case "py":
		// (TODO): different python versions
		cmd = exec.Command("python", f.filename)
	case "lua":
		cmd = exec.Command("lua", f.filename)
	case "ruby":
		cmd = exec.Command("ruby", f.filename)

	default:
		return errors.New("Not a valid filetype!\n[Supported] bin, C" +
			"Go, Python, Lua, Ruby")
	}
	cmd.Stdout, cmd.Stderr, cmd.Stdin = os.Stdout, os.Stderr, os.Stdin

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

func helpMessage() {
	fmt.Println("coderun filename [option]")
	fmt.Println("Options (optional):\n\tcompile\n\trun")
	fmt.Println("It defaults to run")
}

func main() {
	file := newCodeFile(os.Args[1])

	if len(os.Args) > 2 {
		switch os.Args[2] {
		case "compile", "c", "-c", "--compile":
			if err := file.Compile(); err != nil {
				fmt.Errorf("%v\n", err)
			}
		case "run", "r", "-r", "--run", "":
			if err := file.Run(); err != nil {
				fmt.Errorf("%v\n", err)
			}

		default:
			helpMessage()
			os.Exit(1)
		}
	} else {
		if err := file.Run(); err != nil {
			fmt.Errorf("%v\n", err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/intervention-engine/fhir/models"
	_ "github.com/lib/pq"
	"github.com/synthetichealth/bulkfhirloader/bulkloader"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

var debug *bool

func main() {
	// required command line flags
	fhirBundlePath := flag.String("path", "", "Path to fhir bundles to upload")
	mongoServer := flag.String("mongo", "localhost:27017", "MongoDB server url, format: host:27017")
	mongoDBName := flag.String("dbname", "fhir", "MongoDB database name, e.g. 'fhir'")
	pgurl := flag.String("pgurl", "", "Postgres connection string, format: postgresql://username:password@host/dbname?sslmode=disable")

	// optional flags (with sensible defaults)
	numWorkers := flag.Int("workers", 8, "Number of concurrent workers to use")
	reset := flag.Bool("reset", false, "Reset the FHIR collections in Mongo and reset the synth_ma statistics")
	debug = flag.Bool("debug", false, "Display additional debug output")

	flag.Parse()

	if *fhirBundlePath == "" {
		fmt.Println("You must specify a path to the fhir bundles to upload")
		os.Exit(1)
	}

	if *pgurl == "" {
		fmt.Println("You must specify a Postgres connection string")
		os.Exit(1)
	}

	var err error

	// setup the MongoDB connection
	mongoSession, err := mgo.Dial(*mongoServer)
	if err != nil {
		log.Fatal(err)
	}
	defer mongoSession.Close()

	// setup the Postgres connection
	pgDB, err := sql.Open("postgres", *pgurl)
	if err != nil {
		log.Fatal("Failed to connect to Postgres")
	}

	// ping the Postgres db to ensure we connected successfully
	if err = pgDB.Ping(); err != nil {
		log.Fatal(err)
	}
	defer pgDB.Close()

	// optionally reset the data in postgres and mongo (if starting a clean upload)
	if *reset {
		bulkloader.ClearFactTables(pgDB)
		bulkloader.ClearMongoCollections(mongoSession, *mongoDBName)
	}

	// query Postgres for a list of the current subdivisions and diseases we track
	log.Println("Getting latest subdivision and disease information from Postgres...")

	cousubs, err := getCousubs(pgDB)
	if err != nil {
		logDebug(err)
		log.Fatal("Failed to get subdivision list from Postgres")
	}

	diseases, err := getDiseases(pgDB)
	if err != nil {
		logDebug(err)
		log.Fatal("Failed to get disease list from Postgres")
	}

	// create a new WorkerChannel to coordinate workers
	log.Printf("Reading FHIR bundles in %s\n", *fhirBundlePath)

	start := time.Now()
	workerChannel := new(WorkerChannel)
	workerChannel.bundleChannel = make(chan string, 256)

	var wg sync.WaitGroup
	var counter uint64 // total number of FHIR bundles processed

	// spawn workers
	for i := 0; i < *numWorkers; i++ {
		wg.Add(1)
		go worker(&wg, workerChannel.bundleChannel, mongoSession, *mongoDBName, cousubs, diseases, &counter)
	}

	err = filepath.Walk(*fhirBundlePath, workerChannel.visit)
	if err != nil {
		log.Println("An error occured while reading-in FHIR bundles:")
		log.Fatal(err)
	}

	// close the channel when done
	close(workerChannel.bundleChannel)

	// wait for all workers to shut down properly
	wg.Wait()
	log.Printf("%d FHIR bundles read in %f seconds\n", counter, getSecondsSince(start))

	// process the statistics for the uploaded bundles
	bulkloader.CalculatePopulationFacts(mongoSession, *mongoDBName, pgDB)
	log.Printf("Time elapsed: %f seconds\n", getSecondsSince(start))

	bulkloader.CalculateDiseaseFacts(mongoSession, *mongoDBName, pgDB)
	log.Printf("Time elapsed: %f seconds\n", getSecondsSince(start))

	bulkloader.CalculateConditionFacts(mongoSession, *mongoDBName, pgDB)
	log.Printf("Time elapsed: %f seconds\n", getSecondsSince(start))
}

// getCousubs queries the Postgres database for the latest list of subdivision in the
// synth_ma.synth_cousub_dim table.
func getCousubs(db *sql.DB) (*bulkloader.CousubMap, error) {

	rows, err := db.Query(`
		SELECT case when right(cd.cs_name, 5) = ' Town' then substring(cd.cs_name, 1, length(cd.cs_name)-5)
			else cs_name
			end
			, cd.ct_fips
			, cd.cs_fips
		FROM synth_ma.synth_cousub_dim cd`)

	if err != nil {
		return nil, err
	}
	defer rows.Close()

	cousubs := make(bulkloader.CousubMap)

	for rows.Next() {
		var csName, ctFips, csFips string
		var cousub bulkloader.Cousub

		err := rows.Scan(&csName, &ctFips, &csFips)
		if err != nil {
			return nil, err
		}
		cousub.CountyIDFips = ctFips
		cousub.SubCountyIDFips = csFips
		cousubs[csName] = cousub
	}
	return &cousubs, nil
}

// getDiseases queries the Postgres database for the latest list of diseases in the
// synth_ma.synth_condition_dim table.
func getDiseases(db *sql.DB) (*bulkloader.DiseaseMap, error) {

	rows, err := db.Query(`
		SELECT cd.condition_id, coalesce(cd.disease_id, -999), cd.code_system, cd.code
		FROM synth_ma.synth_condition_dim cd`)

	if err != nil {
		return nil, err
	}
	defer rows.Close()

	diseases := make(bulkloader.DiseaseMap)

	for rows.Next() {
		var conditionID, diseaseID int
		var system, code string
		var disease bulkloader.Disease

		err := rows.Scan(&conditionID, &diseaseID, &system, &code)
		if err != nil {
			return nil, err
		}
		disease.ConditionID = conditionID
		disease.DiseaseID = diseaseID
		key := bulkloader.DiseaseKey{
			CodeSystem:  system,
			CodeSysCode: code,
		}
		diseases[key] = disease
	}
	return &diseases, nil
}

// WorkerChannel coordinates the processing of FHIR bundles between several workers.
type WorkerChannel struct {
	bundleChannel chan (string)
}

// visit visits all the FHIR bundles in a specified path, adding each bundle to the
// bundleChannel that feeds the workers.
func (wc *WorkerChannel) visit(path string, f os.FileInfo, err error) error {

	if err != nil {
		return err
	}

	logDebug("Visited: %s\n", path)

	if !f.IsDir() && strings.HasSuffix(path, ".json") {

		// push bundle onto channel
		wc.bundleChannel <- path
		return nil
	}

	logDebug("Processed directory path or non-json file....")
	return nil
}

// worker uses a WorkerChannel to process all of the resources in a single FHIR bundle, specified by the path to that bundle's JSON file.
func worker(wg *sync.WaitGroup, bundles <-chan string, mongoSession *mgo.Session, dbName string, cousubs *bulkloader.CousubMap, diseases *bulkloader.DiseaseMap, counter *uint64) {
	defer wg.Done()

	for {
		select {
		case path, ok := <-bundles:
			if !ok {
				return
			}

			jsonFile, err := os.Open(path)
			if err != nil {
				logDebug("Error opening JSON file:\n", err)
				continue
			}

			jsonData, err := ioutil.ReadAll(jsonFile)
			jsonFile.Close()
			if err != nil {
				logDebug("Error reading JSON data:\n", err)
				continue
			}

			var bundle models.Bundle
			json.Unmarshal(jsonData, &bundle)

			refMap := make(map[string]models.Reference)

			entries := make([]*models.BundleEntryComponent, len(bundle.Entry))
			for i := range bundle.Entry {
				entries[i] = &bundle.Entry[i]
			}

			for _, entry := range entries {
				// Create a new BSON ID and add it to the reference map
				id := bson.NewObjectId().Hex()
				refMap[entry.FullUrl] = models.Reference{
					Reference:    reflect.TypeOf(entry.Resource).Elem().Name() + "/" + id,
					Type:         reflect.TypeOf(entry.Resource).Elem().Name(),
					ReferencedID: id,
					External:     new(bool),
				}
				// Update the resource's UUID to the new BSON ID that was just generated
				bulkloader.SetID(entry.Resource, id)
			}

			// Update all the references to the entries (to reflect newly assigned IDs)
			bulkloader.UpdateAllReferences(entries, refMap)

			resources := make([]interface{}, len(entries))
			for i := range entries {
				resources[i] = entries[i].Resource
			}

			atomic.AddUint64(counter, 1)
			bulkloader.UploadResources(resources, mongoSession, dbName, *cousubs, *diseases)
		} // close the select
	} // close the for
}

func getSecondsSince(start time.Time) float64 {
	return time.Now().Sub(start).Seconds()
}

func logDebug(v ...interface{}) {
	if *debug {
		log.Println(v...)
	}
}
<commit_msg>bulkloader now always resets stats tables in postgres as it will recalculate them each time. Without that, the stats update failed because the rows already existed. reset flag is still required to reset mongo which clears out all patients<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"sync"
	"sync/atomic"
	"time"

	"github.com/intervention-engine/fhir/models"
	_ "github.com/lib/pq"
	"github.com/synthetichealth/bulkfhirloader/bulkloader"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

var debug *bool

func main() {
	// required command line flags
	fhirBundlePath := flag.String("path", "", "Path to fhir bundles to upload")
	mongoServer := flag.String("mongo", "localhost:27017", "MongoDB server url, format: host:27017")
	mongoDBName := flag.String("dbname", "fhir", "MongoDB database name, e.g. 'fhir'")
	pgurl := flag.String("pgurl", "", "Postgres connection string, format: postgresql://username:password@host/dbname?sslmode=disable")

	// optional flags (with sensible defaults)
	numWorkers := flag.Int("workers", 8, "Number of concurrent workers to use")
	reset := flag.Bool("reset", false, "Reset the FHIR collections in Mongo and reset the synth_ma statistics")
	debug = flag.Bool("debug", false, "Display additional debug output")

	flag.Parse()

	if *fhirBundlePath == "" {
		fmt.Println("You must specify a path to the fhir bundles to upload")
		os.Exit(1)
	}

	if *pgurl == "" {
		fmt.Println("You must specify a Postgres connection string")
		os.Exit(1)
	}

	var err error

	// setup the MongoDB connection
	mongoSession, err := mgo.Dial(*mongoServer)
	if err != nil {
		log.Fatal(err)
	}
	defer mongoSession.Close()

	// setup the Postgres connection
	pgDB, err := sql.Open("postgres", *pgurl)
	if err != nil {
		log.Fatal("Failed to connect to Postgres")
	}

	// ping the Postgres db to ensure we connected successfully
	if err = pgDB.Ping(); err != nil {
		log.Fatal(err)
	}
	defer pgDB.Close()

	// GQ: always reset postgres fact tables. reset flag will only clear mongo now
	bulkloader.ClearFactTables(pgDB)

	// optionally reset the data in mongo (if starting a clean upload)
	if *reset {
		bulkloader.ClearMongoCollections(mongoSession, *mongoDBName)
	}

	// query Postgres for a list of the current subdivisions and diseases we track
	log.Println("Getting latest subdivision and disease information from Postgres...")

	cousubs, err := getCousubs(pgDB)
	if err != nil {
		logDebug(err)
		log.Fatal("Failed to get subdivision list from Postgres")
	}

	diseases, err := getDiseases(pgDB)
	if err != nil {
		logDebug(err)
		log.Fatal("Failed to get disease list from Postgres")
	}

	// create a new WorkerChannel to coordinate workers
	log.Printf("Reading FHIR bundles in %s\n", *fhirBundlePath)

	start := time.Now()
	workerChannel := new(WorkerChannel)
	workerChannel.bundleChannel = make(chan string, 256)

	var wg sync.WaitGroup
	var counter uint64 // total number of FHIR bundles processed

	// spawn workers
	for i := 0; i < *numWorkers; i++ {
		wg.Add(1)
		go worker(&wg, workerChannel.bundleChannel, mongoSession, *mongoDBName, cousubs, diseases, &counter)
	}

	err = filepath.Walk(*fhirBundlePath, workerChannel.visit)
	if err != nil {
		log.Println("An error occured while reading-in FHIR bundles:")
		log.Fatal(err)
	}

	// close the channel when done
	close(workerChannel.bundleChannel)

	// wait for all workers to shut down properly
	wg.Wait()
	log.Printf("%d FHIR bundles read in %f seconds\n", counter, getSecondsSince(start))

	// process the statistics for the uploaded bundles
	bulkloader.CalculatePopulationFacts(mongoSession, *mongoDBName, pgDB)
	log.Printf("Time elapsed: %f seconds\n", getSecondsSince(start))

	bulkloader.CalculateDiseaseFacts(mongoSession, *mongoDBName, pgDB)
	log.Printf("Time elapsed: %f seconds\n", getSecondsSince(start))

	bulkloader.CalculateConditionFacts(mongoSession, *mongoDBName, pgDB)
	log.Printf("Time elapsed: %f seconds\n", getSecondsSince(start))
}

// getCousubs queries the Postgres database for the latest list of subdivision in the
// synth_ma.synth_cousub_dim table.
func getCousubs(db *sql.DB) (*bulkloader.CousubMap, error) {

	rows, err := db.Query(`
		SELECT case when right(cd.cs_name, 5) = ' Town' then substring(cd.cs_name, 1, length(cd.cs_name)-5)
			else cs_name
			end
			, cd.ct_fips
			, cd.cs_fips
		FROM synth_ma.synth_cousub_dim cd`)

	if err != nil {
		return nil, err
	}
	defer rows.Close()

	cousubs := make(bulkloader.CousubMap)

	for rows.Next() {
		var csName, ctFips, csFips string
		var cousub bulkloader.Cousub

		err := rows.Scan(&csName, &ctFips, &csFips)
		if err != nil {
			return nil, err
		}
		cousub.CountyIDFips = ctFips
		cousub.SubCountyIDFips = csFips
		cousubs[csName] = cousub
	}
	return &cousubs, nil
}

// getDiseases queries the Postgres database for the latest list of diseases in the
// synth_ma.synth_condition_dim table.
func getDiseases(db *sql.DB) (*bulkloader.DiseaseMap, error) {

	rows, err := db.Query(`
		SELECT cd.condition_id, coalesce(cd.disease_id, -999), cd.code_system, cd.code
		FROM synth_ma.synth_condition_dim cd`)

	if err != nil {
		return nil, err
	}
	defer rows.Close()

	diseases := make(bulkloader.DiseaseMap)

	for rows.Next() {
		var conditionID, diseaseID int
		var system, code string
		var disease bulkloader.Disease

		err := rows.Scan(&conditionID, &diseaseID, &system, &code)
		if err != nil {
			return nil, err
		}
		disease.ConditionID = conditionID
		disease.DiseaseID = diseaseID
		key := bulkloader.DiseaseKey{
			CodeSystem:  system,
			CodeSysCode: code,
		}
		diseases[key] = disease
	}
	return &diseases, nil
}

// WorkerChannel coordinates the processing of FHIR bundles between several workers.
type WorkerChannel struct {
	bundleChannel chan (string)
}

// visit visits all the FHIR bundles in a specified path, adding each bundle to the
// bundleChannel that feeds the workers.
func (wc *WorkerChannel) visit(path string, f os.FileInfo, err error) error {

	if err != nil {
		return err
	}

	logDebug("Visited: %s\n", path)

	if !f.IsDir() && strings.HasSuffix(path, ".json") {

		// push bundle onto channel
		wc.bundleChannel <- path
		return nil
	}

	logDebug("Processed directory path or non-json file....")
	return nil
}

// worker uses a WorkerChannel to process all of the resources in a single FHIR bundle, specified by the path to that bundle's JSON file.
func worker(wg *sync.WaitGroup, bundles <-chan string, mongoSession *mgo.Session, dbName string, cousubs *bulkloader.CousubMap, diseases *bulkloader.DiseaseMap, counter *uint64) {
	defer wg.Done()

	for {
		select {
		case path, ok := <-bundles:
			if !ok {
				return
			}

			jsonFile, err := os.Open(path)
			if err != nil {
				logDebug("Error opening JSON file:\n", err)
				continue
			}

			jsonData, err := ioutil.ReadAll(jsonFile)
			jsonFile.Close()
			if err != nil {
				logDebug("Error reading JSON data:\n", err)
				continue
			}

			var bundle models.Bundle
			json.Unmarshal(jsonData, &bundle)

			refMap := make(map[string]models.Reference)

			entries := make([]*models.BundleEntryComponent, len(bundle.Entry))
			for i := range bundle.Entry {
				entries[i] = &bundle.Entry[i]
			}

			for _, entry := range entries {
				// Create a new BSON ID and add it to the reference map
				id := bson.NewObjectId().Hex()
				refMap[entry.FullUrl] = models.Reference{
					Reference:    reflect.TypeOf(entry.Resource).Elem().Name() + "/" + id,
					Type:         reflect.TypeOf(entry.Resource).Elem().Name(),
					ReferencedID: id,
					External:     new(bool),
				}
				// Update the resource's UUID to the new BSON ID that was just generated
				bulkloader.SetID(entry.Resource, id)
			}

			// Update all the references to the entries (to reflect newly assigned IDs)
			bulkloader.UpdateAllReferences(entries, refMap)

			resources := make([]interface{}, len(entries))
			for i := range entries {
				resources[i] = entries[i].Resource
			}

			atomic.AddUint64(counter, 1)
			bulkloader.UploadResources(resources, mongoSession, dbName, *cousubs, *diseases)
		} // close the select
	} // close the for
}

func getSecondsSince(start time.Time) float64 {
	return time.Now().Sub(start).Seconds()
}

func logDebug(v ...interface{}) {
	if *debug {
		log.Println(v...)
	}
}
<|endoftext|>