<commit_before>package true_git

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

func SyncDevBranchWithStagedFiles(ctx context.Context, gitDir, workTreeCacheDir, commit string) (string, error) {
	var resCommit string

	if err := withWorkTreeCacheLock(ctx, workTreeCacheDir, func() error {
		var err error
		if gitDir, err = filepath.Abs(gitDir); err != nil {
			return fmt.Errorf("bad git dir %s: %s", gitDir, err)
		}

		if workTreeCacheDir, err = filepath.Abs(workTreeCacheDir); err != nil {
			return fmt.Errorf("bad work tree cache dir %s: %s", workTreeCacheDir, err)
		}

		if err := checkSubmoduleConstraint(); err != nil {
			return err
		}

		workTreeDir, err := prepareWorkTree(ctx, gitDir, workTreeCacheDir, commit, true)
		if err != nil {
			return fmt.Errorf("unable to prepare worktree for commit %v: %s", commit, err)
		}

		currentCommitPath := filepath.Join(workTreeCacheDir, "current_commit")
		if err := os.RemoveAll(currentCommitPath); err != nil {
			return fmt.Errorf("unable to remove %s: %s", currentCommitPath, err)
		}

		devBranchName := fmt.Sprintf("werf-dev-%s", commit)
		var isDevBranchExist bool
		if output, err := runGitCmd(ctx, []string{"branch", "--list", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
			return err
		} else {
			isDevBranchExist = output.Len() != 0
		}

		var devHeadCommit string
		if isDevBranchExist {
			if _, err := runGitCmd(ctx, []string{"checkout", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			}

			if output, err := runGitCmd(ctx, []string{"rev-parse", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			} else {
				devHeadCommit = strings.TrimSpace(output.String())
			}
		} else {
			if _, err := runGitCmd(ctx, []string{"checkout", "-b", devBranchName, commit}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			}

			devHeadCommit = commit
		}

		if diffOutput, err := runGitCmd(ctx, []string{"diff", "--cached", devHeadCommit}, gitDir, runGitCmdOptions{}); err != nil {
			return err
		} else if len(diffOutput.Bytes()) == 0 {
			resCommit = devHeadCommit
		} else {
			if _, err := runGitCmd(ctx, []string{"apply"}, workTreeDir, runGitCmdOptions{stdin: diffOutput}); err != nil {
				return err
			}

			if _, err := runGitCmd(ctx, []string{"add", "-A"}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			}

			gitArgs := []string{"-c", "user.email=werf@werf.io", "-c", "user.name=werf", "commit", "-m", time.Now().String()}
			if _, err := runGitCmd(ctx, gitArgs, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			}

			if output, err := runGitCmd(ctx, []string{"rev-parse", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			} else {
				newDevCommit := strings.TrimSpace(output.String())
				resCommit = newDevCommit
			}
		}

		if _, err := runGitCmd(ctx, []string{"checkout", "--detach", resCommit}, workTreeDir, runGitCmdOptions{}); err != nil {
			return err
		}

		if err := ioutil.WriteFile(currentCommitPath, []byte(resCommit+"\n"), 0644); err != nil {
			return fmt.Errorf("unable to write %s: %s", currentCommitPath, err)
		}

		return nil
	}); err != nil {
		return "", err
	}

	return resCommit, nil
}

type runGitCmdOptions struct {
	stdin io.Reader
}

func runGitCmd(ctx context.Context, args []string, dir string, opts runGitCmdOptions) (*bytes.Buffer, error) {
	cmd := exec.Command("git", args...)
	cmd.Dir = dir

	if opts.stdin != nil {
		cmd.Stdin = opts.stdin
	}

	output := setCommandRecordingLiveOutput(ctx, cmd)

	err := cmd.Run()

	cmdWithArgs := strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")
	if debug() {
		fmt.Printf("[DEBUG] %s\n%s\n", cmdWithArgs, output)
	}

	if err != nil {
		return nil, fmt.Errorf("git command %s failed: %s\n%s", cmdWithArgs, err, output)
	}

	return output, err
}

func debug() bool {
	return os.Getenv("WERF_DEBUG_TRUE_GIT") == "1"
}
<commit_msg>[dev] Apply a patch with staged changes also in index<commit_after>package true_git

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

func SyncDevBranchWithStagedFiles(ctx context.Context, gitDir, workTreeCacheDir, commit string) (string, error) {
	var resCommit string

	if err := withWorkTreeCacheLock(ctx, workTreeCacheDir, func() error {
		var err error
		if gitDir, err = filepath.Abs(gitDir); err != nil {
			return fmt.Errorf("bad git dir %s: %s", gitDir, err)
		}

		if workTreeCacheDir, err = filepath.Abs(workTreeCacheDir); err != nil {
			return fmt.Errorf("bad work tree cache dir %s: %s", workTreeCacheDir, err)
		}

		if err := checkSubmoduleConstraint(); err != nil {
			return err
		}

		workTreeDir, err := prepareWorkTree(ctx, gitDir, workTreeCacheDir, commit, true)
		if err != nil {
			return fmt.Errorf("unable to prepare worktree for commit %v: %s", commit, err)
		}

		currentCommitPath := filepath.Join(workTreeCacheDir, "current_commit")
		if err := os.RemoveAll(currentCommitPath); err != nil {
			return fmt.Errorf("unable to remove %s: %s", currentCommitPath, err)
		}

		devBranchName := fmt.Sprintf("werf-dev-%s", commit)
		var isDevBranchExist bool
		if output, err := runGitCmd(ctx, []string{"branch", "--list", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
			return err
		} else {
			isDevBranchExist = output.Len() != 0
		}

		var devHeadCommit string
		if isDevBranchExist {
			if _, err := runGitCmd(ctx, []string{"checkout", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			}

			if output, err := runGitCmd(ctx, []string{"rev-parse", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			} else {
				devHeadCommit = strings.TrimSpace(output.String())
			}
		} else {
			if _, err := runGitCmd(ctx, []string{"checkout", "-b", devBranchName, commit}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			}

			devHeadCommit = commit
		}

		if diffOutput, err := runGitCmd(ctx, []string{"diff", "--cached", devHeadCommit}, gitDir, runGitCmdOptions{}); err != nil {
			return err
		} else if len(diffOutput.Bytes()) == 0 {
			resCommit = devHeadCommit
		} else {
			if _, err := runGitCmd(ctx, []string{"apply", "--index"}, workTreeDir, runGitCmdOptions{stdin: diffOutput}); err != nil {
				return err
			}

			gitArgs := []string{"-c", "user.email=werf@werf.io", "-c", "user.name=werf", "commit", "-m", time.Now().String()}
			if _, err := runGitCmd(ctx, gitArgs, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			}

			if output, err := runGitCmd(ctx, []string{"rev-parse", devBranchName}, workTreeDir, runGitCmdOptions{}); err != nil {
				return err
			} else {
				newDevCommit := strings.TrimSpace(output.String())
				resCommit = newDevCommit
			}
		}

		if _, err := runGitCmd(ctx, []string{"checkout", "--detach", resCommit}, workTreeDir, runGitCmdOptions{}); err != nil {
			return err
		}

		if err := ioutil.WriteFile(currentCommitPath, []byte(resCommit+"\n"), 0644); err != nil {
			return fmt.Errorf("unable to write %s: %s", currentCommitPath, err)
		}

		return nil
	}); err != nil {
		return "", err
	}

	return resCommit, nil
}

type runGitCmdOptions struct {
	stdin io.Reader
}

func runGitCmd(ctx context.Context, args []string, dir string, opts runGitCmdOptions) (*bytes.Buffer, error) {
	cmd := exec.Command("git", args...)
	cmd.Dir = dir

	if opts.stdin != nil {
		cmd.Stdin = opts.stdin
	}

	output := setCommandRecordingLiveOutput(ctx, cmd)

	err := cmd.Run()

	cmdWithArgs := strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")
	if debug() {
		fmt.Printf("[DEBUG] %s\n%s\n", cmdWithArgs, output)
	}

	if err != nil {
		return nil, fmt.Errorf("git command %s failed: %s\n%s", cmdWithArgs, err, output)
	}

	return output, err
}

func debug() bool {
	return os.Getenv("WERF_DEBUG_TRUE_GIT") == "1"
}
<|endoftext|>


<commit_before>// +build ignore

package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strconv"
	"strings"

	"github.com/go-lsst/ncs/drivers/m702"
)

const (
	VM_NEGATIVE_REF_CLAMP1    = 50000.00 // Hz
	VM_POSITIVE_REF_CLAMP1    = 50000.00 // Hz
	VM_ACCEL_RATE             = 3200.000
	VM_MOTOR1_CURRENT_LIMIT   = 1000.0
	VM_SPEED                  = 50000.0
	VM_SPEED_FREQ_REF         = 50000.0
	VM_DRIVE_CURRENT_UNIPOLAR = 99999.999
	VM_DRIVE_CURRENT          = 99999.999
	VM_AC_VOLTAGE_SET         = 690
	VM_AC_VOLTAGE             = 930
	VM_RATED_CURRENT          = 99999.999
)

type Params []m702.Parameter

func (p Params) Len() int      { return len(p) }
func (p Params) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p Params) Less(i, j int) bool {
	ii := int64(p[i].Index[0]*100000) + int64(p[i].MBReg())
	jj := int64(p[j].Index[0]*100000) + int64(p[j].MBReg())
	return ii < jj
}

func main() {
	flag.Parse()
	log.SetPrefix("[gen-ref] ")
	log.SetFlags(0)

	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatalf("error: %v\n", err)
	}
	defer f.Close()

	r := csv.NewReader(f)
	r.Comma = ';'
	r.Comment = '#'

	var params []m702.Parameter
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}

		p := parseRecord(record)
		log.Printf("%#v\n", p)
		params = append(params, p)
	}

	if len(params) == 0 {
		log.Fatalf("no parameters!\n")
	}

	sort.Sort(Params(params))

	o, err := os.Create(flag.Arg(1))
	if err != nil {
		log.Fatalf("could not create file: %v\n", err)
	}
	defer o.Close()

	fmt.Fprintf(o, `package main

import (
	"github.com/go-lsst/ncs/drivers/m702"
)

func init() {
`)
	fmt.Fprintf(o, "\tparams = []m702.Parameter{\n")

	for _, p := range params {
		fmt.Fprintf(
			o,
			"\t\t{Index: [3]int{%d, %d, %d}, Title: %q, DefVal: %q, RW: %v},\n",
			p.Index[0], p.Index[1], p.Index[2], p.Title, p.DefVal, p.RW,
		)
	}
	fmt.Fprintf(o, "\t}\n}\n")
	err = o.Close()
	if err != nil {
		log.Fatalf("error closing output file: %v\n", err)
	}
}

func parseRecord(data []string) m702.Parameter {
	toks := strings.Split(data[0], ".")
	menu, err := strconv.Atoi(toks[0])
	if err != nil {
		log.Fatalf("error: %v\n", err)
	}
	index, err := strconv.Atoi(toks[1])
	if err != nil {
		log.Fatalf("error: %v\n", err)
	}

	rw := strings.TrimSpace(data[4]) == "rw"

	slot := 0 // FIXME
	return m702.Parameter{
		Index:  [3]int{slot, menu, index},
		Title:  strings.TrimSpace(data[1]),
		DefVal: strings.TrimSpace(data[2]),
		RW:     rw,
	}
}
<commit_msg>gen-ref: handle slot.menu.index<commit_after>// +build ignore

package main

import (
	"encoding/csv"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"sort"
	"strings"

	"github.com/go-lsst/ncs/drivers/m702"
)

const (
	VM_NEGATIVE_REF_CLAMP1    = 50000.00 // Hz
	VM_POSITIVE_REF_CLAMP1    = 50000.00 // Hz
	VM_ACCEL_RATE             = 3200.000
	VM_MOTOR1_CURRENT_LIMIT   = 1000.0
	VM_SPEED                  = 50000.0
	VM_SPEED_FREQ_REF         = 50000.0
	VM_DRIVE_CURRENT_UNIPOLAR = 99999.999
	VM_DRIVE_CURRENT          = 99999.999
	VM_AC_VOLTAGE_SET         = 690
	VM_AC_VOLTAGE             = 930
	VM_RATED_CURRENT          = 99999.999
)

type Params []m702.Parameter

func (p Params) Len() int      { return len(p) }
func (p Params) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
func (p Params) Less(i, j int) bool {
	ii := int64(p[i].Index[0]*100000) + int64(p[i].MBReg())
	jj := int64(p[j].Index[0]*100000) + int64(p[j].MBReg())
	return ii < jj
}

func main() {
	flag.Parse()
	log.SetPrefix("[gen-ref] ")
	log.SetFlags(0)

	f, err := os.Open(flag.Arg(0))
	if err != nil {
		log.Fatalf("error: %v\n", err)
	}
	defer f.Close()

	r := csv.NewReader(f)
	r.Comma = ';'
	r.Comment = '#'

	var params []m702.Parameter
	for {
		record, err := r.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}

		p := parseRecord(record)
		log.Printf("%#v\n", p)
		params = append(params, p)
	}

	if len(params) == 0 {
		log.Fatalf("no parameters!\n")
	}

	sort.Sort(Params(params))

	o, err := os.Create(flag.Arg(1))
	if err != nil {
		log.Fatalf("could not create file: %v\n", err)
	}
	defer o.Close()

	fmt.Fprintf(o, `package main

import (
	"github.com/go-lsst/ncs/drivers/m702"
)

func init() {
`)
	fmt.Fprintf(o, "\tparams = []m702.Parameter{\n")

	for _, p := range params {
		fmt.Fprintf(
			o,
			"\t\t{Index: [3]int{%d, %d, %d}, Title: %q, DefVal: %q, RW: %v},\n",
			p.Index[0], p.Index[1], p.Index[2], p.Title, p.DefVal, p.RW,
		)
	}
	fmt.Fprintf(o, "\t}\n}\n")
	err = o.Close()
	if err != nil {
		log.Fatalf("error closing output file: %v\n", err)
	}
}

func parseRecord(data []string) m702.Parameter {
	p, err := m702.NewParameter(data[0])
	if err != nil {
		panic(err)
	}
	p.Title = strings.TrimSpace(data[1])
	p.DefVal = strings.TrimSpace(data[2])
	p.RW = strings.TrimSpace(data[4]) == "rw"
	return p
}
<|endoftext|>


<commit_before>package gen

import (
	"fmt"
	"path/filepath"
	"sync"
)

type IosGenerator struct {
	opt  *Options
	mock *Mock
}

var iwd WidgetsDef

func defineIosWidgets() {
	iwd = WidgetsDef{}
	iwd.Add("button", Widget{
		Name:     "UIButton",
		Textable: true,
		Gravity:  GravityCenter,
		SizeW:    SizeFill,
		SizeH:    SizeWrap,
	})
	iwd.Add("label", Widget{
		Name:     "UILabel",
		Textable: true,
		Gravity:  GravityCenter,
		SizeW:    SizeFill,
		SizeH:    SizeWrap,
	})
	iwd.Add("linear", Widget{
		Textable:    false,
		Orientation: OrientationVertical,
		SizeW:       SizeFill,
		SizeH:       SizeFill,
	})
	iwd.Add("relative", Widget{
		Textable: false,
		SizeW:    SizeFill,
		SizeH:    SizeFill,
	})
}

func (g *IosGenerator) Generate() {
	defineIosWidgets()

	outDir := g.opt.OutDir
	projectDir := filepath.Join(outDir, g.mock.Meta.Ios.Project)

	// TODO Generate base file set

	var wg sync.WaitGroup

	// Generate contents.xcworkspacedata
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosContentsXcWorkspaceData(mock, dir)
	}(g.mock, outDir)

	// Generate main.m
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosMain(mock, dir)
	}(g.mock, outDir)

	// Generate Info.plist
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosInfoPlist(mock, dir)
	}(g.mock, outDir)

	// Generate InfoPlist.strings
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosInfoPlistStrings(mock, dir)
	}(g.mock, outDir)

	// Generate Prefix.pch
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosPch(mock, dir)
	}(g.mock, outDir)

	// Generate Images.xcassets
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosImagesXcAssetsAppIcon(mock, dir)
	}(g.mock, outDir)
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosImagesXcAssetsLaunchImage(mock, dir)
	}(g.mock, outDir)

	// Generate AppDelegate
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosAppDelegateHeader(mock, dir)
	}(g.mock, outDir)
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosAppDelegateImplementation(mock, dir)
	}(g.mock, outDir)

	// Generate ViewControllers
	for _, screen := range g.mock.Screens {
		wg.Add(1)
		go func(mock *Mock, dir string, screen Screen) {
			defer wg.Done()
			genIosViewController(mock, dir, screen)
			genIosViewControllerLayout(mock, dir, screen)
		}(g.mock, projectDir, screen)
	}

	// Generate resources
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosLocalizedStrings(mock, dir)
	}(g.mock, projectDir)
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosColors(mock, dir)
	}(g.mock, projectDir)

	wg.Wait()
}

func genIosContentsXcWorkspaceData(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosContentsXcWorkspaceData(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project+".xcodeproj", "project.xcworkspace", "contents.xcworkspacedata"))
}

func genCodeIosContentsXcWorkspaceData(mock *Mock, buf *CodeBuffer) {
	buf.add(`<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:%s.xcodeproj">
   </FileRef>
</Workspace>
`,
		mock.Meta.Ios.Project)
}

func genIosMain(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosMain(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "main.m"))
}

func genCodeIosMain(mock *Mock, buf *CodeBuffer) {
	buf.add(`#import <UIKit/UIKit.h>

#import "%sAppDelegate.h"

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([%sAppDelegate class]));
    }
}`,
		mock.Meta.Ios.ClassPrefix,
		mock.Meta.Ios.ClassPrefix)
}

func genIosInfoPlist(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosInfoPlist(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.Project+"-Info.plist"))
}

func genCodeIosInfoPlist(mock *Mock, buf *CodeBuffer) {
	buf.add(`<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleDisplayName</key>
	<string>${PRODUCT_NAME}</string>
	<key>CFBundleExecutable</key>
	<string>${EXECUTABLE_NAME}</string>
	<key>CFBundleIdentifier</key>
	<string>%s.${PRODUCT_NAME:rfc1034identifier}</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>${PRODUCT_NAME}</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>1.0</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</dict>
</plist>`,
		mock.Meta.Ios.CompanyIdentifier)
}

func genIosInfoPlistStrings(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosInfoPlistStrings(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "en.lproj", "InfoPlist.strings"))
}

func genCodeIosInfoPlistStrings(mock *Mock, buf *CodeBuffer) {
	buf.add(`/* Localized versions of Info.plist keys */`)
}

func genIosPch(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosPch(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.Project+"-Prefix.pch"))
}

func genCodeIosPch(mock *Mock, buf *CodeBuffer) {
	buf.add(`//
//  Prefix header
//
//  The contents of this file are implicitly included at the beginning of every source file.
//

#import <Availability.h>

#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#endif`)
}

func genIosImagesXcAssetsAppIcon(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosImagesXcAssetsAppIcon(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "Images.xcassets", "AppIcon.appiconset", "Contents.json"))
}

func genCodeIosImagesXcAssetsAppIcon(mock *Mock, buf *CodeBuffer) {
	buf.add(`{
  "images" : [
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}`)
}

func genIosImagesXcAssetsLaunchImage(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosImagesXcAssetsLaunchImage(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "Images.xcassets", "LaunchImage.launchimage", "Contents.json"))
}

func genCodeIosImagesXcAssetsLaunchImage(mock *Mock, buf *CodeBuffer) {
	buf.add(`{
  "images" : [
    {
      "orientation" : "portrait",
      "idiom" : "iphone",
      "extent" : "full-screen",
      "minimum-system-version" : "7.0",
      "scale" : "2x"
    },
    {
      "orientation" : "portrait",
      "idiom" : "iphone",
      "subtype" : "retina4",
      "extent" : "full-screen",
      "minimum-system-version" : "7.0",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}`)
}

func genIosAppDelegateHeader(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosAppDelegateHeader(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.ClassPrefix+"AppDelegate.h"))
}

func genCodeIosAppDelegateHeader(mock *Mock, buf *CodeBuffer) {
	buf.add(`#import <UIKit/UIKit.h>

@interface %sAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end`, mock.Meta.Ios.ClassPrefix)
}

func genIosAppDelegateImplementation(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosAppDelegateImplementation(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.ClassPrefix+"AppDelegate.h"))
}

func genCodeIosAppDelegateImplementation(mock *Mock, buf *CodeBuffer) {
	buf.add(`#import "%sAppDelegate.h"

@implementation %sAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

@end`,
		mock.Meta.Ios.ClassPrefix,
		mock.Meta.Ios.ClassPrefix)
}

func genIosViewController(mock *Mock, dir string, screen Screen) {
	// TODO
	fmt.Println("iOS: ViewController generator: Not implemented...")
}

func genIosViewControllerLayout(mock *Mock, dir string, screen Screen) {
	// TODO
	fmt.Println("iOS: Layout generator: Not implemented...")
}

func genIosLocalizedStrings(mock *Mock, dir string) {
	// TODO
	fmt.Println("iOS: LocalizedString generator: Not implemented...")
}

func genIosColors(mock *Mock, dir string) {
	// TODO
	fmt.Println("iOS: Colors generator: Not implemented...")
}
<commit_msg>Fixed wrong file name for AppDelegate.m.<commit_after>package gen

import (
	"fmt"
	"path/filepath"
	"sync"
)

type IosGenerator struct {
	opt  *Options
	mock *Mock
}

var iwd WidgetsDef

func defineIosWidgets() {
	iwd = WidgetsDef{}
	iwd.Add("button", Widget{
		Name:     "UIButton",
		Textable: true,
		Gravity:  GravityCenter,
		SizeW:    SizeFill,
		SizeH:    SizeWrap,
	})
	iwd.Add("label", Widget{
		Name:     "UILabel",
		Textable: true,
		Gravity:  GravityCenter,
		SizeW:    SizeFill,
		SizeH:    SizeWrap,
	})
	iwd.Add("linear", Widget{
		Textable:    false,
		Orientation: OrientationVertical,
		SizeW:       SizeFill,
		SizeH:       SizeFill,
	})
	iwd.Add("relative", Widget{
		Textable: false,
		SizeW:    SizeFill,
		SizeH:    SizeFill,
	})
}

func (g *IosGenerator) Generate() {
	defineIosWidgets()

	outDir := g.opt.OutDir
	projectDir := filepath.Join(outDir, g.mock.Meta.Ios.Project)

	// TODO Generate base file set

	var wg sync.WaitGroup

	// Generate contents.xcworkspacedata
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosContentsXcWorkspaceData(mock, dir)
	}(g.mock, outDir)

	// Generate main.m
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosMain(mock, dir)
	}(g.mock, outDir)

	// Generate Info.plist
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosInfoPlist(mock, dir)
	}(g.mock, outDir)

	// Generate InfoPlist.strings
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosInfoPlistStrings(mock, dir)
	}(g.mock, outDir)

	// Generate Prefix.pch
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosPch(mock, dir)
	}(g.mock, outDir)

	// Generate Images.xcassets
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosImagesXcAssetsAppIcon(mock, dir)
	}(g.mock, outDir)
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosImagesXcAssetsLaunchImage(mock, dir)
	}(g.mock, outDir)

	// Generate AppDelegate
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosAppDelegateHeader(mock, dir)
	}(g.mock, outDir)
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosAppDelegateImplementation(mock, dir)
	}(g.mock, outDir)

	// Generate ViewControllers
	for _, screen := range g.mock.Screens {
		wg.Add(1)
		go func(mock *Mock, dir string, screen Screen) {
			defer wg.Done()
			genIosViewController(mock, dir, screen)
			genIosViewControllerLayout(mock, dir, screen)
		}(g.mock, projectDir, screen)
	}

	// Generate resources
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosLocalizedStrings(mock, dir)
	}(g.mock, projectDir)
	wg.Add(1)
	go func(mock *Mock, dir string) {
		defer wg.Done()
		genIosColors(mock, dir)
	}(g.mock, projectDir)

	wg.Wait()
}

func genIosContentsXcWorkspaceData(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosContentsXcWorkspaceData(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project+".xcodeproj", "project.xcworkspace", "contents.xcworkspacedata"))
}

func genCodeIosContentsXcWorkspaceData(mock *Mock, buf *CodeBuffer) {
	buf.add(`<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:%s.xcodeproj">
   </FileRef>
</Workspace>
`,
		mock.Meta.Ios.Project)
}

func genIosMain(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosMain(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "main.m"))
}

func genCodeIosMain(mock *Mock, buf *CodeBuffer) {
	buf.add(`#import <UIKit/UIKit.h>

#import "%sAppDelegate.h"

int main(int argc, char * argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([%sAppDelegate class]));
    }
}`,
		mock.Meta.Ios.ClassPrefix,
		mock.Meta.Ios.ClassPrefix)
}

func genIosInfoPlist(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosInfoPlist(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.Project+"-Info.plist"))
}

func genCodeIosInfoPlist(mock *Mock, buf *CodeBuffer) {
	buf.add(`<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleDisplayName</key>
	<string>${PRODUCT_NAME}</string>
	<key>CFBundleExecutable</key>
	<string>${EXECUTABLE_NAME}</string>
	<key>CFBundleIdentifier</key>
	<string>%s.${PRODUCT_NAME:rfc1034identifier}</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>${PRODUCT_NAME}</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>1.0</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</dict>
</plist>`,
		mock.Meta.Ios.CompanyIdentifier)
}

func genIosInfoPlistStrings(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosInfoPlistStrings(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "en.lproj", "InfoPlist.strings"))
}

func genCodeIosInfoPlistStrings(mock *Mock, buf *CodeBuffer) {
	buf.add(`/* Localized versions of Info.plist keys */`)
}

func genIosPch(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosPch(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.Project+"-Prefix.pch"))
}

func genCodeIosPch(mock *Mock, buf *CodeBuffer) {
	buf.add(`//
//  Prefix header
//
//  The contents of this file are implicitly included at the beginning of every source file.
//

#import <Availability.h>

#ifndef __IPHONE_3_0
#warning "This project uses features only available in iOS SDK 3.0 and later."
#endif

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
#endif`)
}

func genIosImagesXcAssetsAppIcon(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosImagesXcAssetsAppIcon(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "Images.xcassets", "AppIcon.appiconset", "Contents.json"))
}

func genCodeIosImagesXcAssetsAppIcon(mock *Mock, buf *CodeBuffer) {
	buf.add(`{
  "images" : [
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}`)
}

func genIosImagesXcAssetsLaunchImage(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosImagesXcAssetsLaunchImage(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, "Images.xcassets", "LaunchImage.launchimage", "Contents.json"))
}

func genCodeIosImagesXcAssetsLaunchImage(mock *Mock, buf *CodeBuffer) {
	buf.add(`{
  "images" : [
    {
      "orientation" : "portrait",
      "idiom" : "iphone",
      "extent" : "full-screen",
      "minimum-system-version" : "7.0",
      "scale" : "2x"
    },
    {
      "orientation" : "portrait",
      "idiom" : "iphone",
      "subtype" : "retina4",
      "extent" : "full-screen",
      "minimum-system-version" : "7.0",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}`)
}

func genIosAppDelegateHeader(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosAppDelegateHeader(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.ClassPrefix+"AppDelegate.h"))
}

func genCodeIosAppDelegateHeader(mock *Mock, buf *CodeBuffer) {
	buf.add(`#import <UIKit/UIKit.h>

@interface %sAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end`, mock.Meta.Ios.ClassPrefix)
}

func genIosAppDelegateImplementation(mock *Mock, dir string) {
	var buf CodeBuffer
	genCodeIosAppDelegateImplementation(mock, &buf)
	genFile(&buf, filepath.Join(dir, mock.Meta.Ios.Project, mock.Meta.Ios.Project, mock.Meta.Ios.ClassPrefix+"AppDelegate.m"))
}

func genCodeIosAppDelegateImplementation(mock *Mock, buf *CodeBuffer) {
	buf.add(`#import "%sAppDelegate.h"

@implementation %sAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

@end`,
		mock.Meta.Ios.ClassPrefix,
		mock.Meta.Ios.ClassPrefix)
}

func genIosViewController(mock *Mock, dir string, screen Screen) {
	// TODO
	fmt.Println("iOS: ViewController generator: Not implemented...")
}

func genIosViewControllerLayout(mock *Mock, dir string, screen Screen) {
	// TODO
	fmt.Println("iOS: Layout generator: Not implemented...")
}

func genIosLocalizedStrings(mock *Mock, dir string) {
	// TODO
	fmt.Println("iOS: LocalizedString generator: Not implemented...")
}

func genIosColors(mock *Mock, dir string) {
	// TODO
	fmt.Println("iOS: Colors generator: Not implemented...")
}
<|endoftext|>


<commit_before>package proxy

import (
	"encoding/binary"
	"fmt"
	"io"
	"net"
	"os"
	"strings"

	"github.com/DimShadoWWW/power-pg/common"
)

var (
	connid = uint64(0)
)

// Pkg PostgreSQL package structure
type Pkg struct {
	Type    byte
	Content []byte
}

// Start function
func Start(localHost, remoteHost *string, remotePort *string, powerCallback common.Callback, msgs chan string, msgCh chan Pkg) {
	fmt.Printf("Proxying from %v to %v\n", localHost, remoteHost)

	localAddr, remoteAddr := getResolvedAddresses(localHost, remoteHost, remotePort)
	listener := getListener(localAddr)

	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Printf("Failed to accept connection '%s'\n", err)
			continue
		}
		connid++

		p := &proxy{
			lconn:  *conn,
			laddr:  localAddr,
			raddr:  remoteAddr,
			erred:  false,
			errsig: make(chan bool),
			prefix: fmt.Sprintf("Connection #%03d ", connid),
		}
		go p.start(powerCallback, msgs, msgCh)
	}
}

func getResolvedAddresses(localHost, remoteHost, remotePort *string) (*net.TCPAddr, *net.TCPAddr) {
	laddr, err := net.ResolveTCPAddr("tcp", *localHost)
	check(err)
	raddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%s", *remoteHost, *remotePort))
	check(err)
	return laddr, raddr
}

func getListener(addr *net.TCPAddr) *net.TCPListener {
	listener, err := net.ListenTCP("tcp", addr)
	check(err)
	return listener
}

type proxy struct {
	sentBytes     uint64
	receivedBytes uint64
	laddr, raddr  *net.TCPAddr
	lconn, rconn  net.TCPConn
	erred         bool
	errsig        chan bool
	prefix        string
	result        *[]string
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}
	if err != io.EOF {
		warn(p.prefix+s, err)
	}
	p.errsig <- true
	p.erred = true
}

func (p *proxy) start(powerCallback common.Callback, msgs chan string, msgCh chan Pkg) {
	// defer p.lconn.conn.Close()
	//connect to remote
	rconn, err := net.DialTCP("tcp", nil, p.raddr)
	if err != nil {
		p.err("Remote connection failed: %s", err)
		return
	}
	p.rconn = *rconn
	// p.rconn.alive = true
	// defer p.rconn.conn.Close()
	//bidirectional copy
	go p.pipe(p.lconn, p.rconn, msgs, msgCh)
	go p.pipe(p.rconn, p.lconn, nil, nil)
	//wait for close...
	<-p.errsig
}

func (p *proxy) pipe(src, dst net.TCPConn, msgs chan string, msgCh chan Pkg) {
	//data direction
	islocal := src == p.lconn
	//directional copy (64k buffer)
	buff := make(ReadBuf, 0xffff)
	newPacket := true
	var msg string
	remainingBytes := 0
	// spaces := regexp.MustCompile("[\n\t ]+")
	if islocal {
		for {
			if remainingBytes == 0 {
				newPacket = true
			}
			var r ReadBuf
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			if msgs != nil {
				msgs <- fmt.Sprintf("Readed bytes: %d\n", n)
			}
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}

			r = buff[:n]
			msgs <- fmt.Sprintf("PostgreSQL full message: %s\n", string(r))
			// if msgCh != nil {
			// 						msgCh <- 	fmt.Sprintf("%#v", string(buff[:n]))}
			if msgs != nil {
				msgs <- fmt.Sprintf("Remaining bytes: %d\n", remainingBytes)
			}
			if msgs != nil {
				msgs <- fmt.Sprintf("newPacket : %v\n", newPacket)
			}
			if msgs != nil {
				msgs <- fmt.Sprintf("len(r) : %v\n", len(r))
			}
			fmt.Println("3")
			// NewP:
			fmt.Println("4")
			if newPacket || (len(msg) > 4 && len(r) > 4 && remainingBytes == 0) {
				fmt.Println("5")
				// remainingBytes = 0
				newPacket = false
				if msgs != nil && msg != "" {
					msgs <- fmt.Sprintf("2 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))
				}
				var msg []byte
				t := r.Byte()
				n = n - 1
				fmt.Println("t: ", string(t))
				switch t {
				case 'Q', 'B', 'C', 'd', 'c', 'f', 'D', 'E', 'H', 'F', 'P', 'p', 'S', 'X':
					// case 'B', 'P':
					// c.rxReadyForQuery(r)
					msgs <- fmt.Sprintf("PostgreSQL pkg type: %s\n", string(t))
					remainingBytes = r.Int32()
					if remainingBytes < 4 {
						fmt.Errorf("ERROR: remainingBytes can't be less than 4 bytes if int32")
					} else {
						remainingBytes = remainingBytes - 4
						if remainingBytes > 0 {
							// if remainingBytes <= n {
							newPacket = true
							msg = append(msg, r.Next(remainingBytes)[:]...)
							// msg = spaces.ReplaceAll(msg, []byte{' '})
							remainingBytes = n - remainingBytes
							if msgCh != nil {
								msgs <- fmt.Sprintf("3 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))
							}
							if msgs != nil {
								msgs <- fmt.Sprintf("3 Remaining bytes: %d \tmsg: %v\n", remainingBytes, msg)
							}

							if msgCh != nil {
								msgCh <- Pkg{
									Type:    t,
									Content: msg,
								}
							}
							remainingBytes = 0
							// }
							// goto NewP
							// } else {
							// 	newPacket = false
							// 	msg = append(msg, r.Next(remainingBytes)[:]...)
							// 	// msg = bytes.Replace(msg, []byte("\n\t"), []byte(" "), -1)
							// 	msg = spaces.ReplaceAll(msg, []byte{' '})
							// 	// msg = []byte(stripchars(string(msg),
							// 	// 	"\n\t"))
							// 	remainingBytes = remainingBytes - n
							// 	if msgs != nil {
							// 		msgs <- fmt.Sprintf("4 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))
							// 	}
						}
					}
					// case :
					// 	fmt.Println("TODO")
					// 	// c.rxReadyForQuery(r)
					// 	remainingBytes = r.int32()
					// 	remainingBytes = remainingBytes - 4
					// 	if remainingBytes > 0 {
					// 		if remainingBytes <= n {
					// 			newPacket = true
					// 			msg = msg + string(r.next(remainingBytes))
					// 			remainingBytes = n - remainingBytes
					// 			if msgCh != nil {
					// msgCh <- 	fmt.Sprintf("3 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))}
					// 			// fmt.Println(msg)
					// 			goto NewP
					// 		} else {
					// 			newPacket = false
					// 			msg = msg + string(r.next(remainingBytes))
					// 			remainingBytes = remainingBytes - n
					// 			if msgCh != nil {
					// msgCh <- 	fmt.Sprintf("4 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))}
					// 		}
					// 	}
					// case rowDescription:
					// case dataRow:
					// case bindComplete:
					// case commandComplete:
					// 	commandTag = CommandTag(r.readCString())
				// case 'Q', 'C', 'd', 'c', 'f', 'D', 'E', 'H', 'F', 'p', 'S', 'X':
				default:
					fmt.Println("6")
					remainingBytes = 0
					// if e := c.processContextFreeMsg(t, r); e != nil && softErr == nil {
					// 	softErr = e
					// }
				}
				remainingBytes = 0
			} else {
				fmt.Println("7")
				remainingBytes = 0
			}
			// r = append(r, buff[:]...)

			// fmt.Println("a")
			// c := src
			// c.reader = bufio.NewReader(src.conn)
			// c.mr.reader = c.reader
			//
			// var t byte
			// var r *msgReader
			// fmt.Println("b")
			// t, r, err := c.rxMsg()
			// fmt.Println("c")
			// if err != nil {
			// 	fmt.Println(err)
			// 	return
			// }
			// fmt.Println("d")
			//
			// if msgCh != nil {
			// msgCh <- 	fmt.Sprintf("t: %#v\n", t)}

			// n, err := src.Read(buff)
			// if err != nil {
			// 	p.err("Read failed '%s'\n", err)
			// 	return
			// }
			// b := buff[:n]
			// //show output
			//
			//
			// b = getModifiedBuffer(b, powerCallback)
			// n, err = dst.Write(b)
			// //
			// //write out result
			// n, err = dst.Write(b)
			// if err != nil {
			// 	p.err("Write failed '%s'\n", err)
			// 	return
			// }
		}
	} else {
		for {
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	}
}

func getModifiedBuffer(buffer []byte, powerCallback common.Callback) []byte {
	if powerCallback == nil || len(buffer) < 1 || string(buffer[0]) != "Q" || string(buffer[5:11]) != "power:" {
		return buffer
	}
	query := powerCallback(string(buffer[5:]))
	return makeMessage(query)
}

func makeMessage(query string) []byte {
	queryArray := make([]byte, 0, 6+len(query))
	queryArray = append(queryArray, 'Q', 0, 0, 0, 0)
	queryArray = append(queryArray, query...)
	queryArray = append(queryArray, 0)
	binary.BigEndian.PutUint32(queryArray[1:], uint32(len(queryArray)-1))
	return queryArray

}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}

func stripchars(str, chr string) string {
	return strings.Map(func(r rune) rune {
		if strings.IndexRune(chr, r) < 0 {
			return r
		}
		return -1
	}, str)
}
<commit_msg>Update<commit_after>package proxy

import (
	"encoding/binary"
	"fmt"
	"io"
	"net"
	"os"
	"strings"

	"github.com/DimShadoWWW/power-pg/common"
)

var (
	connid = uint64(0)
)

// Pkg PostgreSQL package structure
type Pkg struct {
	Type    byte
	Content []byte
}

// Start function
func Start(localHost, remoteHost *string, remotePort *string, powerCallback common.Callback, msgs chan string, msgCh chan Pkg) {
	fmt.Printf("Proxying from %v to %v\n", localHost, remoteHost)

	localAddr, remoteAddr := getResolvedAddresses(localHost, remoteHost, remotePort)
	listener := getListener(localAddr)

	for {
		conn, err := listener.AcceptTCP()
		if err != nil {
			fmt.Printf("Failed to accept connection '%s'\n", err)
			continue
		}
		connid++

		p := &proxy{
			lconn:  *conn,
			laddr:  localAddr,
			raddr:  remoteAddr,
			erred:  false,
			errsig: make(chan bool),
			prefix: fmt.Sprintf("Connection #%03d ", connid),
		}
		go p.start(powerCallback, msgs, msgCh)
	}
}

func getResolvedAddresses(localHost, remoteHost, remotePort *string) (*net.TCPAddr, *net.TCPAddr) {
	laddr, err := net.ResolveTCPAddr("tcp", *localHost)
	check(err)
	raddr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%s", *remoteHost, *remotePort))
	check(err)
	return laddr, raddr
}

func getListener(addr *net.TCPAddr) *net.TCPListener {
	listener, err := net.ListenTCP("tcp", addr)
	check(err)
	return listener
}

type proxy struct {
	sentBytes     uint64
	receivedBytes uint64
	laddr, raddr  *net.TCPAddr
	lconn, rconn  net.TCPConn
	erred         bool
	errsig        chan bool
	prefix        string
	result        *[]string
}

func (p *proxy) err(s string, err error) {
	if p.erred {
		return
	}
	if err != io.EOF {
		warn(p.prefix+s, err)
	}
	p.errsig <- true
	p.erred = true
}

func (p *proxy) start(powerCallback common.Callback, msgs chan string, msgCh chan Pkg) {
	// defer p.lconn.conn.Close()
	//connect to remote
	rconn, err := net.DialTCP("tcp", nil, p.raddr)
	if err != nil {
		p.err("Remote connection failed: %s", err)
		return
	}
	p.rconn = *rconn
	// p.rconn.alive = true
	// defer p.rconn.conn.Close()
	//bidirectional copy
	go p.pipe(p.lconn, p.rconn, msgs, msgCh)
	go p.pipe(p.rconn, p.lconn, nil, nil)
	//wait for close...
	<-p.errsig
}

func (p *proxy) pipe(src, dst net.TCPConn, msgs chan string, msgCh chan Pkg) {
	//data direction
	islocal := src == p.lconn
	//directional copy (64k buffer)
	buff := make(ReadBuf, 0xffff)
	newPacket := true
	var msg string
	remainingBytes := 0
	// spaces := regexp.MustCompile("[\n\t ]+")
	if islocal {
		for {
			if remainingBytes == 0 {
				newPacket = true
			}
			var r ReadBuf
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			if msgs != nil {
				msgs <- fmt.Sprintf("Readed bytes: %d\n", n)
			}
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}

			r = buff[:n]
			msgs <- fmt.Sprintf("PostgreSQL full message: %s\n", string(r))
			// if msgCh != nil {
			// 						msgCh <- 	fmt.Sprintf("%#v", string(buff[:n]))}
			if msgs != nil {
				msgs <- fmt.Sprintf("Remaining bytes: %d\n", remainingBytes)
			}
			if msgs != nil {
				msgs <- fmt.Sprintf("newPacket : %v\n", newPacket)
			}
			if msgs != nil {
				msgs <- fmt.Sprintf("len(r) : %v\n", len(r))
			}
			fmt.Println("3")
			// NewP:
			fmt.Println("4")
			if newPacket || (len(msg) > 4 && len(r) > 4 && remainingBytes == 0) {
				fmt.Println("5")
				// remainingBytes = 0
				newPacket = false
				if msgs != nil && msg != "" {
					msgs <- fmt.Sprintf("2 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))
				}
				var msg []byte
				t := r.Byte()
				n = n - 1
				fmt.Println("t: ", string(t))
				switch t {
				case 'Q', 'B', 'C', 'd', 'c', 'f', 'D', 'E', 'H', 'F', 'P', 'p', 'S', 'X':
					// case 'B', 'P':
					// c.rxReadyForQuery(r)
					msgs <- fmt.Sprintf("PostgreSQL pkg type: %s\n", string(t))
					remainingBytes = r.Int32()
					if remainingBytes < 4 {
						fmt.Errorf("ERROR: remainingBytes can't be less than 4 bytes if int32")
					} else {
						remainingBytes = remainingBytes - 4
						if remainingBytes > 0 {
							if remainingBytes > n {
								remainingBytes = n
							}
							newPacket = true
							msg = append(msg, r.Next(remainingBytes)[:]...)
							// msg = spaces.ReplaceAll(msg, []byte{' '})
							remainingBytes = n - remainingBytes
							if msgCh != nil {
								msgs <- fmt.Sprintf("3 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))
							}
							if msgs != nil {
								msgs <- fmt.Sprintf("3 Remaining bytes: %d \tmsg: %v\n", remainingBytes, msg)
							}

							if msgCh != nil {
								msgCh <- Pkg{
									Type:    t,
									Content: msg,
								}
							}
							remainingBytes = 0
							// goto NewP
							// } else {
							// 	newPacket = false
							// 	msg = append(msg, r.Next(remainingBytes)[:]...)
							// 	// msg = bytes.Replace(msg, []byte("\n\t"), []byte(" "), -1)
							// 	msg = spaces.ReplaceAll(msg, []byte{' '})
							// 	// msg = []byte(stripchars(string(msg),
							// 	// 	"\n\t"))
							// 	remainingBytes = remainingBytes - n
							// 	if msgs != nil {
							// 		msgs <- fmt.Sprintf("4 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))
							// 	}
						}
					}
					// case :
					// 	fmt.Println("TODO")
					// 	// c.rxReadyForQuery(r)
					// 	remainingBytes = r.int32()
					// 	remainingBytes = remainingBytes - 4
					// 	if remainingBytes > 0 {
					// 		if remainingBytes <= n {
					// 			newPacket = true
					// 			msg = msg + string(r.next(remainingBytes))
					// 			remainingBytes = n - remainingBytes
					// 			if msgCh != nil {
					// msgCh <- 	fmt.Sprintf("3 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))}
					// 			// fmt.Println(msg)
					// 			goto NewP
					// 		} else {
					// 			newPacket = false
					// 			msg = msg + string(r.next(remainingBytes))
					// 			remainingBytes = remainingBytes - n
					// 			if msgCh != nil {
					// msgCh <- 	fmt.Sprintf("4 Remaining bytes: %d \tmsg: %s\n", remainingBytes, string(msg))}
					// 		}
					// 	}
					// case rowDescription:
					// case dataRow:
					// case bindComplete:
					// case commandComplete:
					// 	commandTag = CommandTag(r.readCString())
				// case 'Q', 'C', 'd', 'c', 'f', 'D', 'E', 'H', 'F', 'p', 'S', 'X':
				default:
					fmt.Println("6")
					remainingBytes = 0
					// if e := c.processContextFreeMsg(t, r); e != nil && softErr == nil {
					// 	softErr = e
					// }
				}
				remainingBytes = 0
			} else {
				fmt.Println("7")
				remainingBytes = 0
			}
			// r = append(r, buff[:]...)

			// fmt.Println("a")
			// c := src
			// c.reader = bufio.NewReader(src.conn)
			// c.mr.reader = c.reader
			//
			// var t byte
			// var r *msgReader
			// fmt.Println("b")
			// t, r, err := c.rxMsg()
			// fmt.Println("c")
			// if err != nil {
			// 	fmt.Println(err)
			// 	return
			// }
			// fmt.Println("d")
			//
			// if msgCh != nil {
			// msgCh <- 	fmt.Sprintf("t: %#v\n", t)}

			// n, err := src.Read(buff)
			// if err != nil {
			// 	p.err("Read failed '%s'\n", err)
			// 	return
			// }
			// b := buff[:n]
			// //show output
			//
			//
			// b = getModifiedBuffer(b, powerCallback)
			// n, err = dst.Write(b)
			// //
			// //write out result
			// n, err = dst.Write(b)
			// if err != nil {
			// 	p.err("Write failed '%s'\n", err)
			// 	return
			// }
		}
	} else {
		for {
			n, err := src.Read(buff)
			if err != nil {
				p.err("Read failed '%s'\n", err)
				return
			}
			b := buff[:n]
			//write out result
			n, err = dst.Write(b)
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
			if err != nil {
				p.err("Write failed '%s'\n", err)
				return
			}
		}
	}
}

func getModifiedBuffer(buffer []byte, powerCallback common.Callback) []byte {
	if powerCallback == nil || len(buffer) < 1 || string(buffer[0]) != "Q" || string(buffer[5:11]) != "power:" {
		return buffer
	}
	query := powerCallback(string(buffer[5:]))
	return makeMessage(query)
}

func makeMessage(query string) []byte {
	queryArray := make([]byte, 0, 6+len(query))
	queryArray = append(queryArray, 'Q', 0, 0, 0, 0)
	queryArray = append(queryArray, query...)
	queryArray = append(queryArray, 0)
	binary.BigEndian.PutUint32(queryArray[1:], uint32(len(queryArray)-1))
	return queryArray

}

func check(err error) {
	if err != nil {
		warn(err.Error())
		os.Exit(1)
	}
}

func warn(f string, args ...interface{}) {
	fmt.Printf(f+"\n", args...)
}

func stripchars(str, chr string) string {
	return strings.Map(func(r rune) rune {
		if strings.IndexRune(chr, r) < 0 {
			return r
		}
		return -1
	}, str)
}
<|endoftext|>


<commit_before>package geohash

import (
	"bytes"
	"strings"
)

var BASE32 = []byte("0123456789bcdefghjkmnpqrstuvwxyz")

type BoundingBox struct {
	MinLatitude  float64
	MaxLatitude  float64
	MinLongitude float64
	MaxLongitude float64
}

func (bbox *BoundingBox) calcBboxRange(cd int, mask int, isLon bool) {
	if isLon {
		lon := (bbox.MinLongitude + bbox.MaxLongitude) / 2
		if cd&mask > 0 {
			bbox.MinLongitude = lon
		} else {
			bbox.MaxLongitude = lon
		}
	} else {
		lat := (bbox.MinLatitude + bbox.MaxLatitude) / 2
		if cd&mask > 0 {
			bbox.MinLatitude = lat
		} else {
			bbox.MaxLatitude = lat
		}
	}
}

func DecodeBoundingBox(geohash string) *BoundingBox {
	var (
		code string
		cd   int
		mask int
	)
	hashLen := len(geohash)
	isEven := true
	latErr := 90.0
	lonErr := 180.0
	bits := []int{16, 8, 4, 2, 1}
	bbox := &BoundingBox{MinLatitude: -90.0, MaxLatitude: 90.0, MinLongitude: -180.0, MaxLongitude: 180.0}
	geohash = strings.ToLower(geohash)

	for i := 0; i < hashLen; i++ {
		code = geohash[i : i+1]
		cd = bytes.Index(BASE32, []byte(code))

		for j := 0; j < 5; j++ {
			mask = bits[j]
			if isEven {
				lonErr /= 2
				bbox.calcBboxRange(cd, mask, true)
			} else {
				latErr /= 2
				bbox.calcBboxRange(cd, mask, false)
			}
			isEven = !isEven
		}
	}

	return bbox
}

func Encode(lat float64, long float64) string {
	return PrecisionEncode(lat, long, 12)
}

func PrecisionEncode(latitude float64, longitude float64, precision int) string {
	var geohash bytes.Buffer
	var mid float64
	lat := []float64{-90.0, 90.0}
	long := []float64{-180.0, 180.0}
	hashValue := 0
	bit := 0
	isEven := true

	for geohash.Len() < precision {
		if isEven {
			mid = (long[0] + long[1]) / 2
			if longitude > mid {
				hashValue = (hashValue << 1) + 1
				long[0] = mid
			} else {
				hashValue = (hashValue << 1)
				long[1] = mid
			}
		} else {
			mid = (lat[0] + lat[1]) / 2
			if latitude > mid {
				hashValue = (hashValue << 1) + 1
				lat[0] = mid
			} else {
				hashValue = (hashValue << 1)
				lat[1] = mid
			}
		}

		isEven = !isEven
		if bit < 4 {
			bit++
		} else {
			geohash.WriteByte(BASE32[hashValue])
			bit = 0
			hashValue = 0
		}
	}
	return geohash.String()
}
<commit_msg>decode to coordinates<commit_after>package geohash

import (
	"bytes"
	"strings"
)

var BASE32 = []byte("0123456789bcdefghjkmnpqrstuvwxyz")

type BoundingBox struct {
	MinLatitude  float64
	MaxLatitude  float64
	MinLongitude float64
	MaxLongitude float64
}

type Coords struct {
	Latitude  float64
	Longitude float64
}

func Decode(geohash string) *Coords {
	bbox := DecodeBoundingBox(geohash)

	return &Coords{
		Latitude:  (bbox.MinLatitude + bbox.MaxLatitude) / 2,
		Longitude: (bbox.MinLongitude + bbox.MaxLongitude) / 2,
	}
}

func DecodeBoundingBox(geohash string) *BoundingBox {
	var (
		code string
		cd   int
		mask int
	)
	hashLen := len(geohash)
	isEven := true
	latErr := 90.0
	lonErr := 180.0
	bits := []int{16, 8, 4, 2, 1}
	bbox := &BoundingBox{MinLatitude: -90.0, MaxLatitude: 90.0, MinLongitude: -180.0, MaxLongitude: 180.0}
	geohash = strings.ToLower(geohash)

	for i := 0; i < hashLen; i++ {
		code = geohash[i : i+1]
		cd = bytes.Index(BASE32, []byte(code))

		for j := 0; j < 5; j++ {
			mask = bits[j]
			if isEven {
				lonErr /= 2
				bbox.calcBboxRange(cd, mask, true)
			} else {
				latErr /= 2
				bbox.calcBboxRange(cd, mask, false)
			}
			isEven = !isEven
		}
	}

	return bbox
}

func Encode(lat float64, long float64) string {
	return PrecisionEncode(lat, long, 12)
}

func PrecisionEncode(latitude float64, longitude float64, precision int) string {
	var geohash bytes.Buffer
	var mid float64
	lat := []float64{-90.0, 90.0}
	long := []float64{-180.0, 180.0}
	hashValue := 0
	bit := 0
	isEven := true

	for geohash.Len() < precision {
		if isEven {
			mid = (long[0] + long[1]) / 2
			if longitude > mid {
				hashValue = (hashValue << 1) + 1
				long[0] = mid
			} else {
				hashValue = (hashValue << 1)
				long[1] = mid
			}
		} else {
			mid = (lat[0] + lat[1]) / 2
			if latitude > mid {
				hashValue = (hashValue << 1) + 1
				lat[0] = mid
			} else {
				hashValue = (hashValue << 1)
				lat[1] = mid
			}
		}

		isEven = !isEven
		if bit < 4 {
			bit++
		} else {
			geohash.WriteByte(BASE32[hashValue])
			bit = 0
			hashValue = 0
		}
	}
	return geohash.String()
}

func (bbox *BoundingBox) calcBboxRange(cd int, mask int, isLon bool) {
	if isLon {
		lon := (bbox.MinLongitude + bbox.MaxLongitude) / 2
		if cd&mask > 0 {
			bbox.MinLongitude = lon
		} else {
			bbox.MaxLongitude = lon
		}
	} else {
		lat := (bbox.MinLatitude + bbox.MaxLatitude) / 2
		if cd&mask > 0 {
			bbox.MinLatitude = lat
		} else {
			bbox.MaxLatitude = lat
		}
	}
}
<|endoftext|>


<commit_before>// Package proxy is a cli proxy
package proxy

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

	"github.com/gorilla/mux"
	"github.com/micro/cli"
	"github.com/micro/go-api/server"
	"github.com/micro/go-log"
	"github.com/micro/go-micro"
	"github.com/micro/micro/internal/handler"
	"github.com/micro/micro/internal/helper"
	"github.com/micro/micro/internal/stats"
	"github.com/micro/micro/plugin"

	ahandler "github.com/micro/go-api/handler"
	abroker "github.com/micro/go-api/handler/broker"
	aregistry "github.com/micro/go-api/handler/registry"
)

type srv struct {
	*mux.Router
}

var (
	Name         = "go.micro.proxy"
	Address      = ":8081"
	BrokerPath   = "/broker"
	RegistryPath = "/registry"
	RPCPath      = "/rpc"
	CORS         = map[string]bool{"*": true}
)

func (s *srv) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if origin := r.Header.Get("Origin"); CORS[origin] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	} else if len(origin) > 0 && CORS["*"] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	}

	w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
	w.Header().Set("Access-Control-Allow-Credentials", "true")

	if r.Method == "OPTIONS" {
		return
	}

	s.Router.ServeHTTP(w, r)
}

func run(ctx *cli.Context) {
        if len(ctx.GlobalString("server_name")) > 0 {
                Name = ctx.GlobalString("server_name")
        }
        if len(ctx.String("address")) > 0 {
                Address = ctx.String("address")
        }
	if len(ctx.String("cors")) > 0 {
		origins := make(map[string]bool)
		for _, origin := range strings.Split(ctx.String("cors"), ",") {
			origins[origin] = true
		}
		CORS = origins
	}

	// Init plugins
	for _, p := range Plugins() {
		p.Init(ctx)
	}

	var opts []server.Option

	if ctx.GlobalBool("enable_acme") {
		hosts := helper.ACMEHosts(ctx)
		opts = append(opts, server.EnableACME(true))
		opts = append(opts, server.ACMEHosts(hosts...))
	} else if ctx.GlobalBool("enable_tls") {
		config, err := helper.TLSConfig(ctx)
		if err != nil {
			fmt.Println(err.Error())
			return
		}

		opts = append(opts, server.EnableTLS(true))
		opts = append(opts, server.TLSConfig(config))
	}

	r := mux.NewRouter()
	s := &srv{r}

	var h http.Handler = s

	if ctx.GlobalBool("enable_stats") {
		st := stats.New()
		r.Handle("/stats", http.HandlerFunc(st.StatsHandler))
		h = st.ServeHTTP(r)
		st.Start()
		defer st.Stop()
	}

	// new server
	srv := server.NewServer(Address)
	srv.Init(opts...)

	// Initialise Server
	service := micro.NewService(
		micro.Name(Name),
		micro.RegisterTTL(
			time.Duration(ctx.GlobalInt("register_ttl"))*time.Second,
		),
		micro.RegisterInterval(
			time.Duration(ctx.GlobalInt("register_interval"))*time.Second,
		),
	)

	log.Logf("Registering Registry handler at %s", RegistryPath)
	r.Handle(RegistryPath, aregistry.NewHandler(ahandler.WithService(service)))

	log.Logf("Registering RPC handler at %s", RPCPath)
	r.Handle(RPCPath, http.HandlerFunc(handler.RPC))

	log.Logf("Registering Broker handler at %s", BrokerPath)
	br := abroker.NewHandler(
		ahandler.WithService(service),
	)
	r.Handle(BrokerPath, br)

	// reverse wrap handler
	plugins := append(Plugins(), plugin.Plugins()...)
	for i := len(plugins); i > 0; i-- {
		h = plugins[i-1].Handler()(h)
	}

	srv.Handle("/", h)

	if err := srv.Start(); err != nil {
		log.Fatal(err)
	}

	// Run server
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}

	if err := srv.Stop(); err != nil {
		log.Fatal(err)
	}
}

func Commands() []cli.Command {
	command := cli.Command{
		Name:  "proxy",
		Usage: "Run the micro proxy",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:   "address",
				Usage:  "Set the sidecar address e.g 0.0.0.0:8081",
				EnvVar: "MICRO_SIDECAR_ADDRESS",
			},
			cli.StringFlag{
				Name:   "cors",
				Usage:  "Comma separated whitelist of allowed origins for CORS",
				EnvVar: "MICRO_SIDECAR_CORS",
			},
		},
		Action: run,
	}

	for _, p := range Plugins() {
		if cmds := p.Commands(); len(cmds) > 0 {
			command.Subcommands = append(command.Subcommands, cmds...)
		}

		if flags := p.Flags(); len(flags) > 0 {
			command.Flags = append(command.Flags, flags...)
		}
	}

	return []cli.Command{command}
}
<commit_msg>rename env vars<commit_after>// Package proxy is a cli proxy
package proxy

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

	"github.com/gorilla/mux"
	"github.com/micro/cli"
	"github.com/micro/go-api/server"
	"github.com/micro/go-log"
	"github.com/micro/go-micro"
	"github.com/micro/micro/internal/handler"
	"github.com/micro/micro/internal/helper"
	"github.com/micro/micro/internal/stats"
	"github.com/micro/micro/plugin"

	ahandler "github.com/micro/go-api/handler"
	abroker "github.com/micro/go-api/handler/broker"
	aregistry "github.com/micro/go-api/handler/registry"
)

type srv struct {
	*mux.Router
}

var (
	Name         = "go.micro.proxy"
	Address      = ":8081"
	BrokerPath   = "/broker"
	RegistryPath = "/registry"
	RPCPath      = "/rpc"
	CORS         = map[string]bool{"*": true}
)

func (s *srv) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if origin := r.Header.Get("Origin"); CORS[origin] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	} else if len(origin) > 0 && CORS["*"] {
		w.Header().Set("Access-Control-Allow-Origin", origin)
	}

	w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
	w.Header().Set("Access-Control-Allow-Credentials", "true")

	if r.Method == "OPTIONS" {
		return
	}

	s.Router.ServeHTTP(w, r)
}

func run(ctx *cli.Context) {
        if len(ctx.GlobalString("server_name")) > 0 {
                Name = ctx.GlobalString("server_name")
        }
        if len(ctx.String("address")) > 0 {
                Address = ctx.String("address")
        }
	if len(ctx.String("cors")) > 0 {
		origins := make(map[string]bool)
		for _, origin := range strings.Split(ctx.String("cors"), ",") {
			origins[origin] = true
		}
		CORS = origins
	}

	// Init plugins
	for _, p := range Plugins() {
		p.Init(ctx)
	}

	var opts []server.Option

	if ctx.GlobalBool("enable_acme") {
		hosts := helper.ACMEHosts(ctx)
		opts = append(opts, server.EnableACME(true))
		opts = append(opts, server.ACMEHosts(hosts...))
	} else if ctx.GlobalBool("enable_tls") {
		config, err := helper.TLSConfig(ctx)
		if err != nil {
			fmt.Println(err.Error())
			return
		}

		opts = append(opts, server.EnableTLS(true))
		opts = append(opts, server.TLSConfig(config))
	}

	r := mux.NewRouter()
	s := &srv{r}

	var h http.Handler = s

	if ctx.GlobalBool("enable_stats") {
		st := stats.New()
		r.Handle("/stats", http.HandlerFunc(st.StatsHandler))
		h = st.ServeHTTP(r)
		st.Start()
		defer st.Stop()
	}

	// new server
	srv := server.NewServer(Address)
	srv.Init(opts...)

	// Initialise Server
	service := micro.NewService(
		micro.Name(Name),
		micro.RegisterTTL(
			time.Duration(ctx.GlobalInt("register_ttl"))*time.Second,
		),
		micro.RegisterInterval(
			time.Duration(ctx.GlobalInt("register_interval"))*time.Second,
		),
	)

	log.Logf("Registering Registry handler at %s", RegistryPath)
	r.Handle(RegistryPath, aregistry.NewHandler(ahandler.WithService(service)))

	log.Logf("Registering RPC handler at %s", RPCPath)
	r.Handle(RPCPath, http.HandlerFunc(handler.RPC))

	log.Logf("Registering Broker handler at %s", BrokerPath)
	br := abroker.NewHandler(
		ahandler.WithService(service),
	)
	r.Handle(BrokerPath, br)

	// reverse wrap handler
	plugins := append(Plugins(), plugin.Plugins()...)
	for i := len(plugins); i > 0; i-- {
		h = plugins[i-1].Handler()(h)
	}

	srv.Handle("/", h)

	if err := srv.Start(); err != nil {
		log.Fatal(err)
	}

	// Run server
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}

	if err := srv.Stop(); err != nil {
		log.Fatal(err)
	}
}

func Commands() []cli.Command {
	command := cli.Command{
		Name:  "proxy",
		Usage: "Run the micro proxy",
		Flags: []cli.Flag{
			cli.StringFlag{
				Name:   "address",
				Usage:  "Set the proxy address e.g 0.0.0.0:8081",
				EnvVar: "MICRO_PROXY_ADDRESS",
			},
			cli.StringFlag{
				Name:   "cors",
				Usage:  "Comma separated whitelist of allowed origins for CORS",
				EnvVar: "MICRO_PROXY_CORS",
			},
		},
		Action: run,
	}

	for _, p := range Plugins() {
		if cmds := p.Commands(); len(cmds) > 0 {
			command.Subcommands = append(command.Subcommands, cmds...)
		}

		if flags := p.Flags(); len(flags) > 0 {
			command.Flags = append(command.Flags, flags...)
		}
	}

	return []cli.Command{command}
}
<|endoftext|>


<commit_before>package proxy

import (
	disc "github.com/jeffjen/go-discovery"
	"github.com/jeffjen/go-libkv/libkv"
	"github.com/jeffjen/go-proxy/proxy"

	log "github.com/Sirupsen/logrus"
	etcd "github.com/coreos/etcd/client"
	ctx "golang.org/x/net/context"

	"encoding/json"
	"io/ioutil"
	"time"
)

var (
	ProxyConfigKey string

	ConfigReset ctx.CancelFunc

	retry = &proxy.Backoff{}
)

func ConfigKey() string {
	var cfgkey string
	if buf, err := ioutil.ReadFile(".proxycfg"); err == nil {
		cfgkey = string(buf)
	}
	go func() {
		for _ = range time.Tick(2 * time.Minute) {
			ioutil.WriteFile(".proxycfg", []byte(ProxyConfigKey), 0644)
		}
	}()
	return cfgkey
}

func parse(spec string) (*Info, error) {
	var i = new(Info)
	if err := json.Unmarshal([]byte(spec), i); err != nil {
		return nil, err
	}
	if i.Name == "" {
		return nil, ErrMissingName
	}
	return i, nil
}

func get(value string) (targets []*Info) {
	targets = make([]*Info, 0)
	if err := json.Unmarshal([]byte(value), &targets); err != nil {
		log.WithFields(log.Fields{"err": err}).Warning("bad proxy spec")
		targets = nil
	}
	return
}

func doReload(pxycfg []*Info) {
	it, mod := Store.IterateW()
	for elem := range it {
		mod <- &libkv.Value{R: true}
		elem.X.(*Info).Cancel()
	}
	log.WithFields(log.Fields{"count": len(Targets)}).Debug("reload from args")
	for _, spec := range Targets {
		meta, err := parse(spec)
		if err != nil {
			log.WithFields(log.Fields{"err": err}).Warning("reload")
			continue
		}
		if err = Listen(meta); err != nil {
			if err != ErrProxyExist {
				log.WithFields(log.Fields{"err": err}).Debug("reload")
			}
		}
	}
	log.WithFields(log.Fields{"count": len(pxycfg)}).Debug("reload from cfgkey")
	for _, meta := range pxycfg {
		if err := Listen(meta); err != nil {
			if err != ErrProxyExist {
				log.WithFields(log.Fields{"err": err}).Debug("reload")
			}
		}
	}
}

func reloadWorker() chan<- []*Info {
	order := make(chan []*Info)
	go func() {
		for o := range order {
			doReload(o)
		}
	}()
	return order
}

func doWatch(c ctx.Context, watcher etcd.Watcher) <-chan []*Info {
	v := make(chan []*Info)
	go func() {
		evt, err := watcher.Next(c)
		if err != nil {
			log.WithFields(log.Fields{"err": err}).Debug("config")
			retry.Delay()
			v <- nil
		} else {
			retry.Reset()
			if evt.Node.Dir {
				log.WithFields(log.Fields{"key": evt.Node.Key}).Warning("not a valid node")
				v <- nil
			} else {
				switch evt.Action {
				default:
					v <- nil
					break
				case "set":
					v <- get(evt.Node.Value)
					break
				case "del":
				case "expire":
					v <- make([]*Info, 0)
					break
				}
			}
		}
	}()
	return v
}

func followBootStrap() {
	cfg := etcd.Config{Endpoints: disc.Endpoints()}
	kAPI, err := proxy.NewKeysAPI(cfg)
	if err != nil {
		log.WithFields(log.Fields{"err": err}).Warning("bootstrap")
		return
	}
	resp, err := kAPI.Get(RootContext, ProxyConfigKey, nil)
	if err != nil {
		log.WithFields(log.Fields{"err": err}).Warning("bootstrap")
		doReload(make([]*Info, 0))
	} else if resp.Node.Dir {
		log.WithFields(log.Fields{"key": resp.Node.Key}).Warning("not a valid node")
		doReload(make([]*Info, 0))
	} else {
		log.WithFields(log.Fields{"key": resp.Node.Key, "val": resp.Node.Value}).Debug("cfgkey")
		if pxycfg := get(resp.Node.Value); pxycfg != nil {
			doReload(pxycfg)
		} else {
			doReload(make([]*Info, 0))
		}
	}
}

func Follow() {
	followBootStrap() // bootstrap proxy config

	var c ctx.Context

	c, ConfigReset = ctx.WithCancel(RootContext)
	go func() {
		cfg := etcd.Config{Endpoints: disc.Endpoints()}
		watcher, err := proxy.NewWatcher(cfg, ProxyConfigKey, 0)
		if err != nil {
			log.WithFields(log.Fields{"err": err}).Warning("config")
			return
		}
		order := reloadWorker()
		defer close(order)
		for yay := true; yay; {
			v := doWatch(c, watcher)
			select {
			case <-c.Done():
				yay = false
			case proxyTargets, ok := <-v:
				if ok && proxyTargets != nil {
					order <- proxyTargets
				}
				yay = ok
			}
		}
	}()
}
<commit_msg>FIX: default config key for event avoidance<commit_after>package proxy

import (
	disc "github.com/jeffjen/go-discovery"
	"github.com/jeffjen/go-libkv/libkv"
	"github.com/jeffjen/go-proxy/proxy"

	log "github.com/Sirupsen/logrus"
	etcd "github.com/coreos/etcd/client"
	ctx "golang.org/x/net/context"

	"encoding/json"
	"io/ioutil"
	"time"
)

var (
	ProxyConfigKey string = "__nobody__"

	ConfigReset ctx.CancelFunc

	retry = &proxy.Backoff{}
)

func ConfigKey() string {
	var cfgkey string
	if buf, err := ioutil.ReadFile(".proxycfg"); err == nil {
		cfgkey = string(buf)
	}
	go func() {
		for _ = range time.Tick(2 * time.Minute) {
			ioutil.WriteFile(".proxycfg", []byte(ProxyConfigKey), 0644)
		}
	}()
	return cfgkey
}

func parse(spec string) (*Info, error) {
	var i = new(Info)
	if err := json.Unmarshal([]byte(spec), i); err != nil {
		return nil, err
	}
	if i.Name == "" {
		return nil, ErrMissingName
	}
	return i, nil
}

func get(value string) (targets []*Info) {
	targets = make([]*Info, 0)
	if err := json.Unmarshal([]byte(value), &targets); err != nil {
		log.WithFields(log.Fields{"err": err, "value": value}).Warning("config")
		targets = nil
	}
	return
}

func doReload(pxycfg []*Info) {
	it, mod := Store.IterateW()
	for elem := range it {
		mod <- &libkv.Value{R: true}
		elem.X.(*Info).Cancel()
	}
	log.WithFields(log.Fields{"count": len(Targets)}).Debug("reload from args")
	for _, spec := range Targets {
		meta, err := parse(spec)
		if err != nil {
			log.WithFields(log.Fields{"err": err}).Warning("reload")
			continue
		}
		if err = Listen(meta); err != nil {
			if err != ErrProxyExist {
				log.WithFields(log.Fields{"err": err}).Debug("reload")
			}
		}
	}
	log.WithFields(log.Fields{"count": len(pxycfg)}).Debug("reload from cfgkey")
	for _, meta := range pxycfg {
		if err := Listen(meta); err != nil {
			if err != ErrProxyExist {
				log.WithFields(log.Fields{"err": err}).Debug("reload")
			}
		}
	}
}

func reloadWorker() chan<- []*Info {
	order := make(chan []*Info)
	go func() {
		for o := range order {
			doReload(o)
		}
	}()
	return order
}

func doWatch(c ctx.Context, watcher etcd.Watcher) <-chan []*Info {
	v := make(chan []*Info)
	go func() {
		evt, err := watcher.Next(c)
		if err != nil {
			log.WithFields(log.Fields{"err": err}).Debug("config")
			retry.Delay()
			v <- nil
		} else {
			retry.Reset()
			if evt.Node.Dir {
				log.WithFields(log.Fields{"key": evt.Node.Key}).Warning("not a valid node")
				v <- nil
			} else {
				log.WithFields(log.Fields{"key": evt.Node.Key}).Warning("cfgkey")
				switch evt.Action {
				default:
					v <- nil
					break
				case "set":
					v <- get(evt.Node.Value)
					break
				case "del":
				case "expire":
					v <- make([]*Info, 0)
					break
				}
			}
		}
	}()
	return v
}

func followBootStrap() {
	cfg := etcd.Config{Endpoints: disc.Endpoints()}
	kAPI, err := proxy.NewKeysAPI(cfg)
	if err != nil {
		log.WithFields(log.Fields{"err": err}).Warning("bootstrap")
		return
	}
	resp, err := kAPI.Get(RootContext, ProxyConfigKey, nil)
	if err != nil {
		log.WithFields(log.Fields{"err": err}).Warning("bootstrap")
		doReload(make([]*Info, 0))
	} else if resp.Node.Dir {
		log.WithFields(log.Fields{"key": resp.Node.Key}).Warning("not a valid node")
		doReload(make([]*Info, 0))
	} else {
		log.WithFields(log.Fields{"key": resp.Node.Key, "val": resp.Node.Value}).Debug("cfgkey")
		if pxycfg := get(resp.Node.Value); pxycfg != nil {
			doReload(pxycfg)
		} else {
			doReload(make([]*Info, 0))
		}
	}
}

func Follow() {
	followBootStrap() // bootstrap proxy config

	var c ctx.Context

	c, ConfigReset = ctx.WithCancel(RootContext)
	go func() {
		cfg := etcd.Config{Endpoints: disc.Endpoints()}
		watcher, err := proxy.NewWatcher(cfg, ProxyConfigKey, 0)
		if err != nil {
			log.WithFields(log.Fields{"err": err}).Warning("config")
			return
		}
		order := reloadWorker()
		defer close(order)
		for yay := true; yay; {
			v := doWatch(c, watcher)
			select {
			case <-c.Done():
				yay = false
			case proxyTargets, ok := <-v:
				if ok && proxyTargets != nil {
					order <- proxyTargets
				}
				yay = ok
			}
		}
	}()
}
<|endoftext|>


<commit_before>package cli

var all_templates = map[string]string{
	"debug":          default_debug_template,
	"fields":         default_debug_template,
	"editmeta":       default_debug_template,
	"transmeta":      default_debug_template,
	"createmeta":     default_debug_template,
	"issuelinktypes": default_debug_template,
	"list":           default_list_template,
	"table":          default_table_template,
	"view":           default_view_template,
	"edit":           default_edit_template,
	"transitions":    default_transitions_template,
	"issuetypes":     default_issuetypes_template,
	"create":         default_create_template,
	"comment":        default_comment_template,
	"transition":     default_transition_template,
}

const default_debug_template = "{{ . | toJson}}\n"

const default_list_template = "{{ range .issues }}{{ .key | append \":\" | printf \"%-12s\"}} {{ .fields.summary }}\n{{ end }}"

const default_table_template =`+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+{{ "-" | rep 12 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+
| {{ "Issue" | printf "%-14s" }} | {{ "Summary" | printf "%-55s" }} | {{ "Priority" | printf "%-12s" }} | {{ "Status" | printf "%-12s" }} | {{ "Age" | printf "%-10s" }} | {{ "Reporter" | printf "%-12s" }} | {{ "Assignee" | printf "%-12s" }} |
+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+{{ "-" | rep 12 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+
{{ range .issues }}| {{ .key | printf "%-14s"}} | {{ .fields.summary | abbrev 55 | printf "%-55s" }} | {{.fields.priority.name | printf "%-12s" }} | {{.fields.status.name | printf "%-12s" }} | {{.fields.created | age | printf "%-10s" }} | {{.fields.reporter.name | printf "%-12s"}} | {{if .fields.assignee }}{{.fields.assignee.name | printf "%-12s" }}{{else}}<unassigned>{{end}} |
{{ end }}+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+{{ "-" | rep 12 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+
`

const default_view_template = `issue: {{ .key }}
created: {{ .fields.created }}
status: {{ .fields.status.name }}
summary: {{ .fields.summary }}
project: {{ .fields.project.key }}
components: {{ range .fields.components }}{{ .name }} {{end}}
issuetype: {{ .fields.issuetype.name }}
assignee: {{ if .fields.assignee }}{{ .fields.assignee.name }}{{end}}
reporter: {{ .fields.reporter.name }}
watchers: {{ range .fields.customfield_10110 }}{{ .name }} {{end}}
blockers: {{ range .fields.issuelinks }}{{if .outwardIssue}}{{ .outwardIssue.key }}[{{.outwardIssue.fields.status.name}}]{{end}}{{end}}
depends: {{ range .fields.issuelinks }}{{if .inwardIssue}}{{ .inwardIssue.key }}[{{.inwardIssue.fields.status.name}}]{{end}}{{end}}
priority: {{ .fields.priority.name }}
description: |
  {{ or .fields.description "" | indent 2 }}

comments:
{{ range .fields.comment.comments }}  - | # {{.author.name}} at {{.created}}
    {{ or .body "" | indent 4}}
{{end}}
`
const default_edit_template = `update:
  comment:
    - add:
        body: |
          {{ or .overrides.comment "" | indent 10 }}
fields:
  summary: {{ or .overrides.summary .fields.summary }}
  components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{if .overrides.components }}{{ range (split "," .overrides.components)}}
    - name: {{.}}{{end}}{{else}}{{ range .fields.components }}
    - name: {{ .name }}{{end}}{{end}}
  assignee:
    name: {{ if .overrides.assignee }}{{.overrides.assignee}}{{else}}{{if .fields.assignee }}{{ .fields.assignee.name }}{{end}}{{end}}
  reporter:
    name: {{ or .overrides.reporter .fields.reporter.name }}
  # watchers
  customfield_10110: {{ range .fields.customfield_10110 }}
    - name: {{ .name }}{{end}}{{if .overrides.watcher}}
    - name: {{ .overrides.watcher}}{{end}}
  priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
    name: {{ or .overrides.priority .fields.priority.name }}
  description: |
    {{ or .overrides.description (or .fields.description "") | indent 4 }}
`
const default_transitions_template = `{{ range .transitions }}{{.id }}: {{.name}}
{{end}}`

const default_issuetypes_template = `{{ range .projects }}{{ range .issuetypes }}{{color "+bh"}}{{.name | append ":" | printf "%-13s" }}{{color "reset"}} {{.description}}
{{end}}{{end}}`

const default_create_template = `fields:
  project:
    key: {{ .overrides.project }}
  issuetype:
    name: {{ .overrides.issuetype }}
  summary: {{ or .overrides.summary "" }}
  priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
    name: {{ or .overrides.priority "unassigned" }}
  components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range split "," (or .overrides.components "")}}
    - name: {{ . }}{{end}}
  description: |
    {{ or .overrides.description "" | indent 4 }}
  assignee:
    name: {{ or .overrides.assignee "" }}
  reporter:
    name: {{ or .overrides.reporter .overrides.user }}
  # watchers
  customfield_10110:
    - name:
`

const default_comment_template = `body: |
  {{ or .overrides.comment "" | indent 2 }}
`

const default_transition_template = `update:
  comment:
    - add:
        body: |
          {{ or .overrides.comment "" | indent 10 }}
fields:{{if .meta.fields.assignee}}
  assignee:
    name: {{if .overrides.assignee}}{{.overrides.assignee}}{{else}}{{if .fields.assignee}}{{.fields.assignee.name}}{{end}}{{end}}{{end}}{{if .meta.fields.components}}
  components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{if .overrides.components }}{{ range (split "," .overrides.components)}}
    - name: {{.}}{{end}}{{else}}{{ range .fields.components }}
    - name: {{ .name }}{{end}}{{end}}{{end}}{{if .meta.fields.description}}
  description: {{or .overrides.description .fields.description }}{{end}}{{if .meta.fields.fixVersions}}{{if .meta.fields.fixVersions.allowedValues}}
  fixVersions: # Values: {{ range .meta.fields.fixVersions.allowedValues }}{{.name}}, {{end}}{{if .overrides.fixVersions}}{{ range (split "," .overrides.fixVersions)}}
    - name: {{.}}{{end}}{{else}}{{range .fields.fixVersions}}
    - name: {{.}}{{end}}{{end}}{{end}}{{end}}{{if .meta.fields.issuetype}}
  issuetype: # Values: {{ range .meta.fields.issuetype.allowedValues }}{{.name}}, {{end}}
    name: {{if .overrides.issuetype}}{{.overrides.issuetype}}{{else}}{{if .fields.issuetype}}{{.fields.issuetype.name}}{{end}}{{end}}{{end}}{{if .meta.fields.labels}}
  labels: {{range .fields.labels}}
    - {{.}}{{end}}{{if .overrides.labels}}{{range (split "," .overrides.labels)}}
    - {{.}}{{end}}{{end}}{{end}}{{if .meta.fields.priority}}
  priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
    name: {{ or .overrides.priority "unassigned" }}{{end}}{{if .meta.fields.reporter}}
  reporter:
    name: {{if .overrides.reporter}}{{.overrides.reporter}}{{else}}{{if .fields.reporter}}{{.fields.reporter.name}}{{end}}{{end}}{{end}}{{if .meta.fields.resolution}}
  resolution: # Values: {{ range .meta.fields.resolution.allowedValues }}{{.name}}, {{end}}
    name: {{if .overrides.resolution}}{{.overrides.resolution}}{{else if .fields.resolution}}{{.fields.resolution.name}}{{else}}Fixed{{end}}{{end}}{{if .meta.fields.summary}}
  summary: {{or .overrides.summary .fields.summary}}{{end}}{{if .meta.fields.versions.allowedValues}}
  versions: # Values: {{ range .meta.fields.versions.allowedValues }}{{.name}}, {{end}}{{if .overrides.versions}}{{ range (split "," .overrides.versions)}}
    - name: {{.}}{{end}}{{else}}{{range .fields.versions}}
    - name: {{.}}{{end}}{{end}}{{end}}
transition:
  id: {{ .transition.id }}
  name: {{ .transition.name }}
`
<commit_msg>allow create template to specify defalt watchers with -o watchers=...<commit_after>package cli

var all_templates = map[string]string{
	"debug":          default_debug_template,
	"fields":         default_debug_template,
	"editmeta":       default_debug_template,
	"transmeta":      default_debug_template,
	"createmeta":     default_debug_template,
	"issuelinktypes": default_debug_template,
	"list":           default_list_template,
	"table":          default_table_template,
	"view":           default_view_template,
	"edit":           default_edit_template,
	"transitions":    default_transitions_template,
	"issuetypes":     default_issuetypes_template,
	"create":         default_create_template,
	"comment":        default_comment_template,
	"transition":     default_transition_template,
}

const default_debug_template = "{{ . | toJson}}\n"

const default_list_template = "{{ range .issues }}{{ .key | append \":\" | printf \"%-12s\"}} {{ .fields.summary }}\n{{ end }}"

const default_table_template =`+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+{{ "-" | rep 12 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+
| {{ "Issue" | printf "%-14s" }} | {{ "Summary" | printf "%-55s" }} | {{ "Priority" | printf "%-12s" }} | {{ "Status" | printf "%-12s" }} | {{ "Age" | printf "%-10s" }} | {{ "Reporter" | printf "%-12s" }} | {{ "Assignee" | printf "%-12s" }} |
+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+{{ "-" | rep 12 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+
{{ range .issues }}| {{ .key | printf "%-14s"}} | {{ .fields.summary | abbrev 55 | printf "%-55s" }} | {{.fields.priority.name | printf "%-12s" }} | {{.fields.status.name | printf "%-12s" }} | {{.fields.created | age | printf "%-10s" }} | {{.fields.reporter.name | printf "%-12s"}} | {{if .fields.assignee }}{{.fields.assignee.name | printf "%-12s" }}{{else}}<unassigned>{{end}} |
{{ end }}+{{ "-" | rep 16 }}+{{ "-" | rep 57 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+{{ "-" | rep 12 }}+{{ "-" | rep 14 }}+{{ "-" | rep 14 }}+
`

const default_view_template = `issue: {{ .key }}
created: {{ .fields.created }}
status: {{ .fields.status.name }}
summary: {{ .fields.summary }}
project: {{ .fields.project.key }}
components: {{ range .fields.components }}{{ .name }} {{end}}
issuetype: {{ .fields.issuetype.name }}
assignee: {{ if .fields.assignee }}{{ .fields.assignee.name }}{{end}}
reporter: {{ .fields.reporter.name }}
watchers: {{ range .fields.customfield_10110 }}{{ .name }} {{end}}
blockers: {{ range .fields.issuelinks }}{{if .outwardIssue}}{{ .outwardIssue.key }}[{{.outwardIssue.fields.status.name}}]{{end}}{{end}}
depends: {{ range .fields.issuelinks }}{{if .inwardIssue}}{{ .inwardIssue.key }}[{{.inwardIssue.fields.status.name}}]{{end}}{{end}}
priority: {{ .fields.priority.name }}
description: |
  {{ or .fields.description "" | indent 2 }}

comments:
{{ range .fields.comment.comments }}  - | # {{.author.name}} at {{.created}}
    {{ or .body "" | indent 4}}
{{end}}
`
const default_edit_template = `update:
  comment:
    - add:
        body: |
          {{ or .overrides.comment "" | indent 10 }}
fields:
  summary: {{ or .overrides.summary .fields.summary }}
  components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{if .overrides.components }}{{ range (split "," .overrides.components)}}
    - name: {{.}}{{end}}{{else}}{{ range .fields.components }}
    - name: {{ .name }}{{end}}{{end}}
  assignee:
    name: {{ if .overrides.assignee }}{{.overrides.assignee}}{{else}}{{if .fields.assignee }}{{ .fields.assignee.name }}{{end}}{{end}}
  reporter:
    name: {{ or .overrides.reporter .fields.reporter.name }}
  # watchers
  customfield_10110: {{ range .fields.customfield_10110 }}
    - name: {{ .name }}{{end}}{{if .overrides.watcher}}
    - name: {{ .overrides.watcher}}{{end}}
  priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
    name: {{ or .overrides.priority .fields.priority.name }}
  description: |
    {{ or .overrides.description (or .fields.description "") | indent 4 }}
`
const default_transitions_template = `{{ range .transitions }}{{.id }}: {{.name}}
{{end}}`

const default_issuetypes_template = `{{ range .projects }}{{ range .issuetypes }}{{color "+bh"}}{{.name | append ":" | printf "%-13s" }}{{color "reset"}} {{.description}}
{{end}}{{end}}`

const default_create_template = `fields:
  project:
    key: {{ .overrides.project }}
  issuetype:
    name: {{ .overrides.issuetype }}
  summary: {{ or .overrides.summary "" }}
  priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
    name: {{ or .overrides.priority "unassigned" }}
  components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{ range split "," (or .overrides.components "")}}
    - name: {{ . }}{{end}}
  description: |
    {{ or .overrides.description "" | indent 4 }}
  assignee:
    name: {{ or .overrides.assignee "" }}
  reporter:
    name: {{ or .overrides.reporter .overrides.user }}
  # watchers
  customfield_10110: {{ range split "," (or .overrides.watchers "")}}
    - name: {{.}}{{end}}
    - name:
`

const default_comment_template = `body: |
  {{ or .overrides.comment "" | indent 2 }}
`

const default_transition_template = `update:
  comment:
    - add:
        body: |
          {{ or .overrides.comment "" | indent 10 }}
fields:{{if .meta.fields.assignee}}
  assignee:
    name: {{if .overrides.assignee}}{{.overrides.assignee}}{{else}}{{if .fields.assignee}}{{.fields.assignee.name}}{{end}}{{end}}{{end}}{{if .meta.fields.components}}
  components: # Values: {{ range .meta.fields.components.allowedValues }}{{.name}}, {{end}}{{if .overrides.components }}{{ range (split "," .overrides.components)}}
    - name: {{.}}{{end}}{{else}}{{ range .fields.components }}
    - name: {{ .name }}{{end}}{{end}}{{end}}{{if .meta.fields.description}}
  description: {{or .overrides.description .fields.description }}{{end}}{{if .meta.fields.fixVersions}}{{if .meta.fields.fixVersions.allowedValues}}
  fixVersions: # Values: {{ range .meta.fields.fixVersions.allowedValues }}{{.name}}, {{end}}{{if .overrides.fixVersions}}{{ range (split "," .overrides.fixVersions)}}
    - name: {{.}}{{end}}{{else}}{{range .fields.fixVersions}}
    - name: {{.}}{{end}}{{end}}{{end}}{{end}}{{if .meta.fields.issuetype}}
  issuetype: # Values: {{ range .meta.fields.issuetype.allowedValues }}{{.name}}, {{end}}
    name: {{if .overrides.issuetype}}{{.overrides.issuetype}}{{else}}{{if .fields.issuetype}}{{.fields.issuetype.name}}{{end}}{{end}}{{end}}{{if .meta.fields.labels}}
  labels: {{range .fields.labels}}
    - {{.}}{{end}}{{if .overrides.labels}}{{range (split "," .overrides.labels)}}
    - {{.}}{{end}}{{end}}{{end}}{{if .meta.fields.priority}}
  priority: # Values: {{ range .meta.fields.priority.allowedValues }}{{.name}}, {{end}}
    name: {{ or .overrides.priority "unassigned" }}{{end}}{{if .meta.fields.reporter}}
  reporter:
    name: {{if .overrides.reporter}}{{.overrides.reporter}}{{else}}{{if .fields.reporter}}{{.fields.reporter.name}}{{end}}{{end}}{{end}}{{if .meta.fields.resolution}}
  resolution: # Values: {{ range .meta.fields.resolution.allowedValues }}{{.name}}, {{end}}
    name: {{if .overrides.resolution}}{{.overrides.resolution}}{{else if .fields.resolution}}{{.fields.resolution.name}}{{else}}Fixed{{end}}{{end}}{{if .meta.fields.summary}}
  summary: {{or .overrides.summary .fields.summary}}{{end}}{{if .meta.fields.versions.allowedValues}}
  versions: # Values: {{ range .meta.fields.versions.allowedValues }}{{.name}}, {{end}}{{if .overrides.versions}}{{ range (split "," .overrides.versions)}}
    - name: {{.}}{{end}}{{else}}{{range .fields.versions}}
    - name: {{.}}{{end}}{{end}}{{end}}
transition:
  id: {{ .transition.id }}
  name: {{ .transition.name }}
`
<|endoftext|>


<commit_before>package docconv

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"time"
)

// Response payload sent back to the requestor
type Response struct {
	Body  string            `json:"body"`
	Meta  map[string]string `json:"meta"`
	MSecs uint32            `json:"msecs"`
}

// Determine the mime type by the file's extension
func MimeTypeByExtension(filename string) string {
	switch path.Ext(filename) {
	case ".doc":
		return "application/msword"
	case ".docx":
		return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
	case ".odt":
		return "application/vnd.oasis.opendocument.text"
	case ".pages":
		return "application/vnd.apple.pages"
	case ".pdf":
		return "application/pdf"
	case ".rtf":
		return "application/rtf"
	case ".xml":
		return "text/xml"
	case ".xhtml", ".html", ".htm":
		return "text/html"
	case ".txt":
		return "text/plain"
	}
	return "application/octet-stream"
}

// TODO(dhowden): Refactor this.
// Convert a file to plain text & meta data
func Convert(r io.Reader, mimeType string, readability bool) (*Response, error) {
	start := time.Now()

	var body string
	var meta map[string]string
	var err error
	switch mimeType {
	case "application/msword", "application/vnd.ms-word":
		body, meta, err = ConvertDoc(r)

	case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
		body, meta, err = ConvertDocx(r)

	case "application/vnd.oasis.opendocument.text":
		body, meta, err = ConvertODT(r)

	case "application/vnd.apple.pages", "application/x-iwork-pages-sffpages":
		body, meta, err = ConvertPages(r)

	case "application/pdf":
		body, meta, err = ConvertPDF(r)

	case "application/rtf", "application/x-rtf", "text/rtf", "text/richtext":
		body, meta, err = ConvertRTF(r)

	case "text/html":
		body, meta, err = ConvertHTML(r, readability)

	case "text/url":
		body, meta, err = ConvertURL(r, readability)

	case "text/xml", "application/xml":
		body, meta, err = ConvertXML(r)

	case "text/plain":
		var b []byte
		b, err = ioutil.ReadAll(r)
		body = string(b)
	}

	if err != nil {
		return nil, fmt.Errorf("error converting data: %v", err)
	}

	return &Response{
		Body:  body,
		Meta:  meta,
		MSecs: uint32(time.Since(start) / time.Millisecond),
	}, nil
}

// TODO(dhowden): Refactor this.
// Convert a file given a path
func ConvertPath(path string) (*Response, error) {
	mimeType := MimeTypeByExtension(path)

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

	return Convert(f, mimeType, true)
}

// TODO(dhowden): Refactor this.
// Convert a file given a path
func ConvertPathReadability(path string, readability bool) ([]byte, error) {
	mimeType := MimeTypeByExtension(path)

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

	data, err := Convert(f, mimeType, readability)
	if err != nil {
		return nil, err
	}
	return json.Marshal(data)
}
<commit_msg>add mime types of images<commit_after>package docconv

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"time"
)

// Response payload sent back to the requestor
type Response struct {
	Body  string            `json:"body"`
	Meta  map[string]string `json:"meta"`
	MSecs uint32            `json:"msecs"`
}

// Determine the mime type by the file's extension
func MimeTypeByExtension(filename string) string {
	switch path.Ext(filename) {
	case ".doc":
		return "application/msword"
	case ".docx":
		return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
	case ".odt":
		return "application/vnd.oasis.opendocument.text"
	case ".pages":
		return "application/vnd.apple.pages"
	case ".pdf":
		return "application/pdf"
	case ".rtf":
		return "application/rtf"
	case ".xml":
		return "text/xml"
	case ".xhtml", ".html", ".htm":
		return "text/html"
	case ".jpg", ".jpeg", ".jpe", ".jfif", ".jfif-tbnl":
		return "image/jpeg"
	case ".png":
		return "image/png"
	case ".tif":
		return "image/tif"
	case ".tiff":
		return "image/tiff"
	case ".txt":
		return "text/plain"
	}
	return "application/octet-stream"
}

// TODO(dhowden): Refactor this.
// Convert a file to plain text & meta data
func Convert(r io.Reader, mimeType string, readability bool) (*Response, error) {
	start := time.Now()

	var body string
	var meta map[string]string
	var err error
	switch mimeType {
	case "application/msword", "application/vnd.ms-word":
		body, meta, err = ConvertDoc(r)

	case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
		body, meta, err = ConvertDocx(r)

	case "application/vnd.oasis.opendocument.text":
		body, meta, err = ConvertODT(r)

	case "application/vnd.apple.pages", "application/x-iwork-pages-sffpages":
		body, meta, err = ConvertPages(r)

	case "application/pdf":
		body, meta, err = ConvertPDF(r)

	case "application/rtf", "application/x-rtf", "text/rtf", "text/richtext":
		body, meta, err = ConvertRTF(r)

	case "text/html":
		body, meta, err = ConvertHTML(r, readability)

	case "text/url":
		body, meta, err = ConvertURL(r, readability)

	case "text/xml", "application/xml":
		body, meta, err = ConvertXML(r)

	case "text/plain":
		var b []byte
		b, err = ioutil.ReadAll(r)
		body = string(b)
	}

	if err != nil {
		return nil, fmt.Errorf("error converting data: %v", err)
	}

	return &Response{
		Body:  body,
		Meta:  meta,
		MSecs: uint32(time.Since(start) / time.Millisecond),
	}, nil
}

// TODO(dhowden): Refactor this.
// Convert a file given a path
func ConvertPath(path string) (*Response, error) {
	mimeType := MimeTypeByExtension(path)

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

	return Convert(f, mimeType, true)
}

// TODO(dhowden): Refactor this.
// Convert a file given a path
func ConvertPathReadability(path string, readability bool) ([]byte, error) {
	mimeType := MimeTypeByExtension(path)

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

	data, err := Convert(f, mimeType, readability)
	if err != nil {
		return nil, err
	}
	return json.Marshal(data)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"strings"
	"unicode"
)

func registerFilters(db *DB) {
	db.AddFilter(noHyphens)
	db.AddFilter(noUnderscore)
	db.AddFilter(notCapitalized)
	db.AddFilter(noReferenceToGo)
	db.AddFilter(noReferenceToGolang)
	db.AddFilter(validPackageNames)
}

func noHyphens(name string) error {
	if strings.Contains(name, "-") {
		return errors.New("Don't put hyphens, that's ugly.")
	}
	return nil
}

func noUnderscore(name string) error {
	if strings.Contains(name, "_") {
		return errors.New("Don't put underscores, that's ugly.")
	}
	return nil
}

func notCapitalized(name string) error {
	for _, r := range []rune(name) {
		if unicode.IsUpper(r) {
			return errors.New("Don't put uppercase characters, it's too enterprisey.")
		}
	}
	return nil
}

func noReferenceToGo(name string) error {
	if strings.Contains(strings.ToLower(name), "go") {
		return errors.New("Don't mention 'go' in your package name. Go is implicit in any package. Go is absolute and infinitesimal. Other languages should rename their packages; for instance rails-ruby, python-django remove any ambiguity.")
	}
	return nil
}

func noReferenceToGolang(name string) error {
	if strings.Contains(strings.ToLower(name), "golang") {
		return errors.New("The name of Go is Go, not Golang. You don't say Javalang, or Rubylang, or Pythonlang, do you?")
	}
	return nil
}

var errInvalidPackage = "That's not even a valid package name: %s!" +
	" Read the spec: http://golang.org/ref/spec#Package_clause"

func validPackageNames(name string) error {
	if len(name) < 1 {
		return fmt.Errorf(errInvalidPackage, "the name can't be blank")
	}

	for i, rest := range []rune(name) {
		if i == 0 {
			if !unicode.IsLetter(rest) {
				return fmt.Errorf(errInvalidPackage, "the first character must be a letter")
			}
		}

		switch {
		case unicode.IsLetter(rest):
		case unicode.IsDigit(rest):
			// ok
		default:
			return fmt.Errorf(errInvalidPackage, "all the characters (but the first) must be either letters or digits")
		}
	}

	return nil
}
<commit_msg>Accept underscore/hyphens part of valid go package names.<commit_after>package main

import (
	"errors"
	"fmt"
	"strings"
	"unicode"
)

func registerFilters(db *DB) {
	db.AddFilter(noHyphens)
	db.AddFilter(noUnderscore)
	db.AddFilter(notCapitalized)
	db.AddFilter(noReferenceToGo)
	db.AddFilter(noReferenceToGolang)
	db.AddFilter(validPackageNames)
}

func noHyphens(name string) error {
	if strings.Contains(name, "-") {
		return errors.New("Don't put hyphens, that's ugly.")
	}
	return nil
}

func noUnderscore(name string) error {
	if strings.Contains(name, "_") {
		return errors.New("Don't put underscores, that's ugly.")
	}
	return nil
}

func notCapitalized(name string) error {
	for _, r := range []rune(name) {
		if unicode.IsUpper(r) {
			return errors.New("Don't put uppercase characters, it's too enterprisey.")
		}
	}
	return nil
}

func noReferenceToGo(name string) error {
	if strings.Contains(strings.ToLower(name), "go") {
		return errors.New("Don't mention 'go' in your package name. Go is implicit in any package. Go is absolute and infinitesimal. Other languages should rename their packages; for instance rails-ruby, python-django remove any ambiguity.")
	}
	return nil
}

func noReferenceToGolang(name string) error {
	if strings.Contains(strings.ToLower(name), "golang") {
		return errors.New("The name of Go is Go, not Golang. You don't say Javalang, or Rubylang, or Pythonlang, do you?")
	}
	return nil
}

var errInvalidPackage = "That's not even a valid package name: %s!" +
	" Read the spec: http://golang.org/ref/spec#Package_clause"

func validPackageNames(name string) error {
	if len(name) < 1 {
		return fmt.Errorf(errInvalidPackage, "the name can't be blank")
	}

	for i, r := range []rune(name) {
		if i == 0 {
			if !unicode.IsLetter(r) {
				return fmt.Errorf(errInvalidPackage, "the first character must be a letter")
			}
		}

		switch {
		case unicode.IsLetter(r):
		case unicode.IsDigit(r):
		case r == '-':
		case r == '_':
			// ok
		default:
			return fmt.Errorf(errInvalidPackage, "all the characters (but the first) must be either letters or digits")
		}
	}

	return nil
}
<|endoftext|>