<commit_before>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"os"
)

func main() {
	var (
		clientOV           *ov.OVClient
		enc_name           = "EN1"
		new_enclosure_name = "RenamedEnclosure"
		path               = "/name"
		op                 = "replace"
	)
	ovc := clientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		600,
		"*")

	enclosure_create_map := ov.EnclosureCreateMap{
		EnclosureGroupUri: "/rest/enclosure_groups/05100faa-c26b-4a16-8055-911568418190",
		Hostname:          os.Getenv("ENCLOSURE_HOSTNAME"),
		Username:          os.Getenv("ENCLOSURE_USERNAME"),
		Password:          os.Getenv("ENCLOSURE_PASSWORD"),
		LicensingIntent:   "OneView",
		InitialScopeUris:  make([]string, 0),
	}

	fmt.Println("#----------------Create Enclosure---------------#")

	err := ovc.CreateEnclosure(enclosure_create_map)
	if err != nil {
		fmt.Println("Enclosure Creation Failed: ", err)
	} else {
		fmt.Println("Enclosure created successfully...")
	}

	sort := ""

	enc_list, err := ovc.GetEnclosures("", "", "", sort, "")
	if err != nil {
		fmt.Println("Enclosure Retrieval Failed: ", err)
	} else {
		fmt.Println("#----------------Enclosure List---------------#")

		for i := 0; i < len(enc_list.Members); i++ {
			fmt.Println(enc_list.Members[i].Name)
		}
	}

	enclosure, err := ovc.GetEnclosureByName(enc_name)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Enclosure by Name----------------#")
		fmt.Println(enclosure.Name)
	}

	uri := enclosure.URI
	enclosure, err = ovc.GetEnclosurebyUri(uri)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Enclosure by URI--------------#")
		fmt.Println(enclosure.Name)
	}

	err = ovc.UpdateEnclosure(op, path, new_enclosure_name, enclosure)
	if err != nil {
		fmt.Println(err)
	}

	enc_list, err = ovc.GetEnclosures("", "", "", sort, "")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Enclosure List after Updating---------#")
		for i := 0; i < len(enc_list.Members); i++ {
			fmt.Println(enc_list.Members[i].Name)
		}
	}

	err = ovc.DeleteEnclosure(new_enclosure_name)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Deleted Enclosure successfully...")
	}
}
<commit_msg>missing fields in struct.<commit_after>package main

import (
	"fmt"
	"github.com/HewlettPackard/oneview-golang/ov"
	"os"
)

func main() {
	var (
		clientOV           *ov.OVClient
		enc_name           = "EN1"
	)
	ovc := clientOV.NewOVClient(
		os.Getenv("ONEVIEW_OV_USER"),
		os.Getenv("ONEVIEW_OV_PASSWORD"),
		os.Getenv("ONEVIEW_OV_DOMAIN"),
		os.Getenv("ONEVIEW_OV_ENDPOINT"),
		false,
		800,
		"*")

	/*enclosure_create_map := ov.EnclosureCreateMap{
		EnclosureGroupUri: "/rest/enclosure_groups/05100faa-c26b-4a16-8055-911568418190",
		Hostname:          os.Getenv("ENCLOSURE_HOSTNAME"),
		Username:          os.Getenv("ENCLOSURE_USERNAME"),
		Password:          os.Getenv("ENCLOSURE_PASSWORD"),
		LicensingIntent:   "OneView",
		InitialScopeUris:  make([]string, 0),
	}

	fmt.Println("#----------------Create Enclosure---------------#")

	err := ovc.CreateEnclosure(enclosure_create_map)
	if err != nil {
		fmt.Println("Enclosure Creation Failed: ", err)
	} else {
		fmt.Println("Enclosure created successfully...")
	}*/

	sort := ""

	enc_list, err := ovc.GetEnclosures("", "", "", sort, "")
	if err != nil {
		fmt.Println("Enclosure Retrieval Failed: ", err)
	} else {
		fmt.Println("#----------------Enclosure List---------------#")

		for i := 0; i < len(enc_list.Members); i++ {
			fmt.Println(enc_list.Members[i].Name)
		}
	}

	enclosure, err := ovc.GetEnclosureByName(enc_name)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Enclosure by Name----------------#")
		fmt.Println(enclosure.Name)
	}

	uri := enclosure.URI
	enclosure, err = ovc.GetEnclosurebyUri(uri)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Enclosure by URI--------------#")
		fmt.Println(enclosure.Name)
	}

	/*err = ovc.UpdateEnclosure(op, path, new_enclosure_name, enclosure)
	if err != nil {
		fmt.Println(err)
	}

	enc_list, err = ovc.GetEnclosures("", "", "", sort, "")
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("#----------------Enclosure List after Updating---------#")
		for i := 0; i < len(enc_list.Members); i++ {
			fmt.Println(enc_list.Members[i].Name)
		}
	}

	err = ovc.DeleteEnclosure(new_enclosure_name)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Deleted Enclosure successfully...")
	}*/
}
<|endoftext|>


<commit_before>package gotwilio

import (
	"encoding/json"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

// These are the paramters to use when you want Twilio to use callback urls.
// See http://www.twilio.com/docs/api/rest/making-calls for more info.
type CallbackParameters struct {
	Url                  string // Required
	Method               string // Optional
	FallbackUrl          string // Optional
	FallbackMethod       string // Optional
	StatusCallback       string // Optional
	StatusCallbackMethod string // Optional
	SendDigits           string // Optional
	IfMachine            string // False, Continue or Hangup; http://www.twilio.com/docs/errors/21207
	Timeout              int    // Optional
	Record               bool   // Optional
}

// VoiceResponse contains the details about successful voice calls.
type VoiceResponse struct {
	Sid            string   `json:"sid"`
	DateCreated    string   `json:"date_created"`
	DateUpdated    string   `json:"date_updated"`
	ParentCallSid  string   `json:"parent_call_sid"`
	AccountSid     string   `json:"account_sid"`
	To             string   `json:"to"`
	ToFormatted    string   `json:"to_formatted"`
	From           string   `json:"from"`
	FromFormatted  string   `json:"from_formatted"`
	PhoneNumberSid string   `json:"phone_number_sid"`
	Status         string   `json:"status"`
	StartTime      string   `json:"start_time"`
	EndTime        string   `json:"end_time"`
	Duration       int      `json:"duration"`
	Price          *float32 `json:"price,omitempty"`
	Direction      string   `json:"direction"`
	AnsweredBy     string   `json:"answered_by"`
	ApiVersion     string   `json:"api_version"`
	Annotation     string   `json:"annotation"`
	ForwardedFrom  string   `json:"forwarded_from"`
	GroupSid       string   `json:"group_sid"`
	CallerName     string   `json:"caller_name"`
	Uri            string   `json:"uri"`
	// TODO: handle SubresourceUris
}

// Returns VoiceResponse.DateCreated as a time.Time object
// instead of a string.
func (vr *VoiceResponse) DateCreatedAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.DateCreated)
}

// Returns VoiceResponse.DateUpdated as a time.Time object
// instead of a string.
func (vr *VoiceResponse) DateUpdatedAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.DateUpdated)
}

// Returns VoiceResponse.StartTime as a time.Time object
// instead of a string.
func (vr *VoiceResponse) StartTimeAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.StartTime)
}

// Returns VoiceResponse.EndTime as a time.Time object
// instead of a string.
func (vr *VoiceResponse) EndTimeAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.EndTime)
}

// Returns a CallbackParameters type with the specified url and
// CallbackParameters.Timeout set to 60.
func NewCallbackParameters(url string) *CallbackParameters {
	return &CallbackParameters{Url: url, Timeout: 60}
}

// Place a voice call with a list of callbacks specified.
func (twilio *Twilio) CallWithUrlCallbacks(from, to string, callbackParameters *CallbackParameters) (*VoiceResponse, *Exception, error) {
	formValues := url.Values{}
	formValues.Set("From", from)
	formValues.Set("To", to)
	formValues.Set("Url", callbackParameters.Url)

	// Optional values
	if callbackParameters.Method != "" {
		formValues.Set("Method", callbackParameters.Method)
	}
	if callbackParameters.FallbackUrl != "" {
		formValues.Set("FallbackUrl", callbackParameters.FallbackUrl)
	}
	if callbackParameters.FallbackMethod != "" {
		formValues.Set("FallbackMethod", callbackParameters.FallbackMethod)
	}
	if callbackParameters.StatusCallback != "" {
		formValues.Set("StatusCallback", callbackParameters.StatusCallback)
	}
	if callbackParameters.StatusCallbackMethod != "" {
		formValues.Set("StatusCallbackMethod", callbackParameters.StatusCallbackMethod)
	}
	if callbackParameters.SendDigits != "" {
		formValues.Set("SendDigits", callbackParameters.SendDigits)
	}
	if callbackParameters.IfMachine != "" {
		formValues.Set("IfMachine", callbackParameters.IfMachine)
	}
	if callbackParameters.Timeout != 0 {
		formValues.Set("Timeout", strconv.Itoa(callbackParameters.Timeout))
	}
	if callbackParameters.Record {
		formValues.Set("Record", "true")
	} else {
		formValues.Set("Record", "false")
	}

	return twilio.voicePost(formValues)
}

// Place a voice call with an ApplicationSid specified.
func (twilio *Twilio) CallWithApplicationCallbacks(from, to, applicationSid string) (*VoiceResponse, *Exception, error) {
	formValues := url.Values{}
	formValues.Set("From", from)
	formValues.Set("To", to)
	formValues.Set("ApplicationSid", applicationSid)

	return twilio.voicePost(formValues)
}

// This is a private method that has the common bits for making a voice call.
func (twilio *Twilio) voicePost(formValues url.Values) (*VoiceResponse, *Exception, error) {
	var voiceResponse *VoiceResponse
	var exception *Exception
	twilioUrl := twilio.BaseUrl + "/Accounts/" + twilio.AccountSid + "/Calls.json"

	res, err := twilio.post(formValues, twilioUrl)
	if err != nil {
		return voiceResponse, exception, err
	}
	defer res.Body.Close()

	decoder := json.NewDecoder(res.Body)

	if res.StatusCode != http.StatusCreated {
		exception = new(Exception)
		err = decoder.Decode(exception)

		// We aren't checking the error because we don't actually care.
		// It's going to be passed to the client either way.
		return voiceResponse, exception, err
	}

	voiceResponse = new(VoiceResponse)
	err = decoder.Decode(voiceResponse)
	return voiceResponse, exception, err
}
<commit_msg>Add machine detection params<commit_after>package gotwilio

import (
	"encoding/json"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

// These are the paramters to use when you want Twilio to use callback urls.
// See http://www.twilio.com/docs/api/rest/making-calls for more info.
type CallbackParameters struct {
	Url                     string // Required
	Method                  string // Optional
	FallbackUrl             string // Optional
	FallbackMethod          string // Optional
	StatusCallback          string // Optional
	StatusCallbackMethod    string // Optional
	SendDigits              string // Optional
	IfMachine               string // False, Continue or Hangup; http://www.twilio.com/docs/errors/21207
	Timeout                 int    // Optional
	Record                  bool   // Optional
	MachineDetection        string // Optional
	MachineDetectionTimeout int    // Optional
}

// VoiceResponse contains the details about successful voice calls.
type VoiceResponse struct {
	Sid            string   `json:"sid"`
	DateCreated    string   `json:"date_created"`
	DateUpdated    string   `json:"date_updated"`
	ParentCallSid  string   `json:"parent_call_sid"`
	AccountSid     string   `json:"account_sid"`
	To             string   `json:"to"`
	ToFormatted    string   `json:"to_formatted"`
	From           string   `json:"from"`
	FromFormatted  string   `json:"from_formatted"`
	PhoneNumberSid string   `json:"phone_number_sid"`
	Status         string   `json:"status"`
	StartTime      string   `json:"start_time"`
	EndTime        string   `json:"end_time"`
	Duration       int      `json:"duration"`
	Price          *float32 `json:"price,omitempty"`
	Direction      string   `json:"direction"`
	AnsweredBy     string   `json:"answered_by"`
	ApiVersion     string   `json:"api_version"`
	Annotation     string   `json:"annotation"`
	ForwardedFrom  string   `json:"forwarded_from"`
	GroupSid       string   `json:"group_sid"`
	CallerName     string   `json:"caller_name"`
	Uri            string   `json:"uri"`
	// TODO: handle SubresourceUris
}

// Returns VoiceResponse.DateCreated as a time.Time object
// instead of a string.
func (vr *VoiceResponse) DateCreatedAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.DateCreated)
}

// Returns VoiceResponse.DateUpdated as a time.Time object
// instead of a string.
func (vr *VoiceResponse) DateUpdatedAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.DateUpdated)
}

// Returns VoiceResponse.StartTime as a time.Time object
// instead of a string.
func (vr *VoiceResponse) StartTimeAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.StartTime)
}

// Returns VoiceResponse.EndTime as a time.Time object
// instead of a string.
func (vr *VoiceResponse) EndTimeAsTime() (time.Time, error) {
	return time.Parse(time.RFC1123Z, vr.EndTime)
}

// Returns a CallbackParameters type with the specified url and
// CallbackParameters.Timeout set to 60.
func NewCallbackParameters(url string) *CallbackParameters {
	return &CallbackParameters{Url: url, Timeout: 60}
}

// Place a voice call with a list of callbacks specified.
func (twilio *Twilio) CallWithUrlCallbacks(from, to string, callbackParameters *CallbackParameters) (*VoiceResponse, *Exception, error) {
	formValues := url.Values{}
	formValues.Set("From", from)
	formValues.Set("To", to)
	formValues.Set("Url", callbackParameters.Url)

	// Optional values
	if callbackParameters.Method != "" {
		formValues.Set("Method", callbackParameters.Method)
	}
	if callbackParameters.FallbackUrl != "" {
		formValues.Set("FallbackUrl", callbackParameters.FallbackUrl)
	}
	if callbackParameters.FallbackMethod != "" {
		formValues.Set("FallbackMethod", callbackParameters.FallbackMethod)
	}
	if callbackParameters.StatusCallback != "" {
		formValues.Set("StatusCallback", callbackParameters.StatusCallback)
	}
	if callbackParameters.StatusCallbackMethod != "" {
		formValues.Set("StatusCallbackMethod", callbackParameters.StatusCallbackMethod)
	}
	if callbackParameters.SendDigits != "" {
		formValues.Set("SendDigits", callbackParameters.SendDigits)
	}
	if callbackParameters.IfMachine != "" {
		formValues.Set("IfMachine", callbackParameters.IfMachine)
	}
	if callbackParameters.Timeout != 0 {
		formValues.Set("Timeout", strconv.Itoa(callbackParameters.Timeout))
	}
	if callbackParameters.MachineDetection != "" {
		formValues.Set("MachineDetection", callbackParameters.MachineDetection)
	}
	if callbackParameters.MachineDetectionTimeout != 0 {
		formValues.Set(
			"MachineDetectionTimeout",
			strconv.Itoa(callbackParameters.MachineDetectionTimeout),
		)
	}

	if callbackParameters.Record {
		formValues.Set("Record", "true")
	} else {
		formValues.Set("Record", "false")
	}

	return twilio.voicePost(formValues)
}

// Place a voice call with an ApplicationSid specified.
func (twilio *Twilio) CallWithApplicationCallbacks(from, to, applicationSid string) (*VoiceResponse, *Exception, error) {
	formValues := url.Values{}
	formValues.Set("From", from)
	formValues.Set("To", to)
	formValues.Set("ApplicationSid", applicationSid)

	return twilio.voicePost(formValues)
}

// This is a private method that has the common bits for making a voice call.
func (twilio *Twilio) voicePost(formValues url.Values) (*VoiceResponse, *Exception, error) {
	var voiceResponse *VoiceResponse
	var exception *Exception
	twilioUrl := twilio.BaseUrl + "/Accounts/" + twilio.AccountSid + "/Calls.json"

	res, err := twilio.post(formValues, twilioUrl)
	if err != nil {
		return voiceResponse, exception, err
	}
	defer res.Body.Close()

	decoder := json.NewDecoder(res.Body)

	if res.StatusCode != http.StatusCreated {
		exception = new(Exception)
		err = decoder.Decode(exception)

		// We aren't checking the error because we don't actually care.
		// It's going to be passed to the client either way.
		return voiceResponse, exception, err
	}

	voiceResponse = new(VoiceResponse)
	err = decoder.Decode(voiceResponse)
	return voiceResponse, exception, err
}
<|endoftext|>


<commit_before>package transloadit

import (
	"errors"
	"fmt"
	"gopkg.in/fsnotify.v1"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path"
	"strings"
	"time"
)

type WatchOptions struct {
	Input      string
	Output     string
	Watch      bool
	TemplateId string
	NotifyUrl  string
	Steps      map[string]map[string]interface{}
	Preserve   bool
}

type Watcher struct {
	client          *Client
	options         *WatchOptions
	stopped         bool
	Error           chan error
	Done            chan *AssemblyInfo
	Change          chan string
	end             chan bool
	lastEvents      map[string]time.Time
	processingFiles map[string]bool
}

func (client *Client) Watch(options *WatchOptions) *Watcher {

	watcher := &Watcher{
		client:          client,
		options:         options,
		Error:           make(chan error),
		Done:            make(chan *AssemblyInfo),
		Change:          make(chan string),
		end:             make(chan bool),
		lastEvents:      make(map[string]time.Time),
		processingFiles: make(map[string]bool),
	}

	watcher.start()

	return watcher

}

func (watcher *Watcher) start() {

	watcher.processDir()

	if watcher.options.Watch {
		go watcher.startWatcher()
	}

}

func (watcher *Watcher) Stop() {

	if watcher.stopped {
		return
	}

	watcher.stopped = true

	watcher.end <- true
	close(watcher.Done)
	close(watcher.Error)
	close(watcher.Change)
	close(watcher.end)
}

func (watcher *Watcher) processDir() {

	files, err := ioutil.ReadDir(watcher.options.Input)
	if err != nil {
		watcher.error(err)
		return
	}

	input := watcher.options.Input

	for _, file := range files {
		if !file.IsDir() {
			go watcher.processFile(path.Join(input, file.Name()))
		}
	}

}

func (watcher *Watcher) processFile(name string) {

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

	// Add file to blacklist
	watcher.processingFiles[name] = true

	assembly := watcher.client.CreateAssembly()

	if watcher.options.TemplateId != "" {
		assembly.TemplateId = watcher.options.TemplateId
	}

	if watcher.options.NotifyUrl != "" {
		assembly.NotifyUrl = watcher.options.NotifyUrl
	}

	for name, step := range watcher.options.Steps {
		assembly.AddStep(name, step)
	}

	assembly.Blocking = true

	assembly.AddReader("file", path.Base(name), file)

	info, err := assembly.Upload()
	if err != nil {
		watcher.error(err)
		return
	}

	if info.Error != "" {
		watcher.error(errors.New(info.Error))
		return
	}

	for stepName, results := range info.Results {
		for index, result := range results {
			go func() {
				watcher.downloadResult(stepName, index, result)
				watcher.handleOriginalFile(name)
				delete(watcher.processingFiles, name)
				watcher.Done <- info
			}()
		}
	}
}

func (watcher *Watcher) downloadResult(stepName string, index int, result *FileInfo) {

	fileName := fmt.Sprintf("%s_%d_%s", stepName, index, result.Name)

	resp, err := http.Get(result.Url)
	if err != nil {
		watcher.error(err)
		return
	}

	defer resp.Body.Close()

	out, err := os.Create(path.Join(watcher.options.Output, fileName))
	if err != nil {
		watcher.error(err)
		return
	}

	defer out.Close()

	io.Copy(out, resp.Body)

}

func (watcher *Watcher) startWatcher() {

	fsWatcher, err := fsnotify.NewWatcher()
	if err != nil {
		watcher.error(err)
	}

	defer fsWatcher.Close()

	if err = fsWatcher.Add(watcher.options.Input); err != nil {
		watcher.error(err)
	}

	go func() {
		for {

			if watcher.stopped {
				return
			}

			time.Sleep(time.Second)
			now := time.Now()

			for name, lastEvent := range watcher.lastEvents {
				diff := now.Sub(lastEvent)
				if diff > (time.Millisecond * 500) {
					delete(watcher.lastEvents, name)
					watcher.Change <- name
					watcher.processFile(name)
				}
			}

		}
	}()

	for {
		select {
		case <-watcher.end:
			return
		case err := <-fsWatcher.Errors:
			watcher.error(err)
		case evt := <-fsWatcher.Events:
			// Ignore the event if the file is currently processed
			if _, ok := watcher.processingFiles[evt.Name]; ok {
				return
			}
			if evt.Op&fsnotify.Create == fsnotify.Create || evt.Op&fsnotify.Write == fsnotify.Write {
				watcher.lastEvents[evt.Name] = time.Now()
			}
		}
	}

}

func (watcher *Watcher) handleOriginalFile(name string) {

	var err error
	if watcher.options.Preserve {
		_, file := path.Split(name)
		err = os.Rename(name, watcher.options.Output+"/-original_0_"+basename(file))
	} else {
		err = os.Remove(name)
	}

	if err != nil {
		watcher.error(err)
	}

}

func (watcher *Watcher) error(err error) {
	watcher.Error <- err
}

func basename(name string) string {
	i := strings.LastIndex(name, string(os.PathSeparator))
	return name[i+1:]
}
<commit_msg>Add some logging for now<commit_after>package transloadit

import (
	"errors"
	"fmt"
	"gopkg.in/fsnotify.v1"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"strings"
	"time"
)

type WatchOptions struct {
	Input      string
	Output     string
	Watch      bool
	TemplateId string
	NotifyUrl  string
	Steps      map[string]map[string]interface{}
	Preserve   bool
}

type Watcher struct {
	client          *Client
	options         *WatchOptions
	stopped         bool
	Error           chan error
	Done            chan *AssemblyInfo
	Change          chan string
	end             chan bool
	lastEvents      map[string]time.Time
	processingFiles map[string]bool
}

func (client *Client) Watch(options *WatchOptions) *Watcher {

	watcher := &Watcher{
		client:          client,
		options:         options,
		Error:           make(chan error),
		Done:            make(chan *AssemblyInfo),
		Change:          make(chan string),
		end:             make(chan bool),
		lastEvents:      make(map[string]time.Time),
		processingFiles: make(map[string]bool),
	}

	watcher.start()

	return watcher

}

func (watcher *Watcher) start() {

	watcher.processDir()

	if watcher.options.Watch {
		go watcher.startWatcher()
	}

}

func (watcher *Watcher) Stop() {

	if watcher.stopped {
		return
	}

	watcher.stopped = true

	watcher.end <- true
	close(watcher.Done)
	close(watcher.Error)
	close(watcher.Change)
	close(watcher.end)
}

func (watcher *Watcher) processDir() {

	files, err := ioutil.ReadDir(watcher.options.Input)
	if err != nil {
		watcher.error(err)
		return
	}

	input := watcher.options.Input

	for _, file := range files {
		if !file.IsDir() {
			go watcher.processFile(path.Join(input, file.Name()))
		}
	}

}

func (watcher *Watcher) processFile(name string) {

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

	// Add file to blacklist
	log.Printf("Adding to blacklist: '%s'", name)
	watcher.processingFiles[name] = true

	assembly := watcher.client.CreateAssembly()

	if watcher.options.TemplateId != "" {
		assembly.TemplateId = watcher.options.TemplateId
	}

	if watcher.options.NotifyUrl != "" {
		assembly.NotifyUrl = watcher.options.NotifyUrl
	}

	for name, step := range watcher.options.Steps {
		assembly.AddStep(name, step)
	}

	assembly.Blocking = true

	assembly.AddReader("file", path.Base(name), file)

	info, err := assembly.Upload()
	if err != nil {
		watcher.error(err)
		return
	}

	if info.Error != "" {
		watcher.error(errors.New(info.Error))
		return
	}

	for stepName, results := range info.Results {
		for index, result := range results {
			go func() {
				watcher.downloadResult(stepName, index, result)
				watcher.handleOriginalFile(name)
				log.Printf("Removing from blacklist: '%s'", name)
				delete(watcher.processingFiles, name)
				watcher.Done <- info
			}()
		}
	}
}

func (watcher *Watcher) downloadResult(stepName string, index int, result *FileInfo) {

	fileName := fmt.Sprintf("%s_%d_%s", stepName, index, result.Name)

	resp, err := http.Get(result.Url)
	if err != nil {
		watcher.error(err)
		return
	}

	defer resp.Body.Close()

	out, err := os.Create(path.Join(watcher.options.Output, fileName))
	if err != nil {
		watcher.error(err)
		return
	}

	defer out.Close()

	io.Copy(out, resp.Body)

}

func (watcher *Watcher) startWatcher() {

	fsWatcher, err := fsnotify.NewWatcher()
	if err != nil {
		watcher.error(err)
	}

	defer fsWatcher.Close()

	if err = fsWatcher.Add(watcher.options.Input); err != nil {
		watcher.error(err)
	}

	go func() {
		for {

			if watcher.stopped {
				return
			}

			time.Sleep(time.Second)
			now := time.Now()

			for name, lastEvent := range watcher.lastEvents {
				diff := now.Sub(lastEvent)
				if diff > (time.Millisecond * 500) {
					delete(watcher.lastEvents, name)
					watcher.Change <- name
					watcher.processFile(name)
				}
			}

		}
	}()

	for {
		select {
		case <-watcher.end:
			return
		case err := <-fsWatcher.Errors:
			watcher.error(err)
		case evt := <-fsWatcher.Events:
			// Ignore the event if the file is currently processed
			log.Printf("Checking blacklist: '%s'", evt.Name)
			if _, ok := watcher.processingFiles[evt.Name]; ok == true {
				return
			}
			if evt.Op&fsnotify.Create == fsnotify.Create || evt.Op&fsnotify.Write == fsnotify.Write {
				watcher.lastEvents[evt.Name] = time.Now()
			}
		}
	}

}

func (watcher *Watcher) handleOriginalFile(name string) {

	var err error
	if watcher.options.Preserve {
		_, file := path.Split(name)
		err = os.Rename(name, watcher.options.Output+"/-original_0_"+basename(file))
	} else {
		err = os.Remove(name)
	}

	if err != nil {
		watcher.error(err)
	}

}

func (watcher *Watcher) error(err error) {
	watcher.Error <- err
}

func basename(name string) string {
	i := strings.LastIndex(name, string(os.PathSeparator))
	return name[i+1:]
}
<|endoftext|>


<commit_before>// weedo.go
package weedo

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"net/textproto"
	"strconv"
	"strings"
)

var defaultClient *Client

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	defaultClient = NewClient("localhost:9333")
}

type Fid struct {
	Id, Key, Cookie uint64
}

type Client struct {
	master  *Master
	volumes map[uint64]*Volume
	filers  map[string]*Filer
}

func NewClient(masterUrl string, filerUrls ...string) *Client {
	filers := make(map[string]*Filer)
	for _, url := range filerUrls {
		filer := NewFiler(url)
		filers[filer.Url] = filer
	}
	return &Client{
		master:  NewMaster(masterUrl),
		volumes: make(map[uint64]*Volume),
		filers:  filers,
	}
}

func (c *Client) Master() *Master {
	return c.master
}

func (c *Client) Volume(volumeId, collection string) (*Volume, error) {
	vid, _ := strconv.ParseUint(volumeId, 10, 32)
	if vid == 0 {
		fid, _ := ParseFid(volumeId)
		vid = fid.Id
	}

	if vid == 0 {
		return nil, errors.New("id malformed")
	}

	if v, ok := c.volumes[vid]; ok {
		return v, nil
	}
	vol, err := c.Master().lookup(volumeId, collection)
	if err != nil {
		return nil, err
	}

	c.volumes[vid] = vol

	return vol, nil
}

func (c *Client) Filer(url string) *Filer {
	filer := NewFiler(url)
	if v, ok := c.filers[filer.Url]; ok {
		return v
	}

	c.filers[filer.Url] = filer
	return filer
}

func ParseFid(s string) (fid Fid, err error) {
	a := strings.Split(s, ",")
	if len(a) != 2 || len(a[1]) <= 8 {
		return fid, errors.New("Fid format invalid")
	}
	if fid.Id, err = strconv.ParseUint(a[0], 10, 32); err != nil {
		return
	}
	index := len(a[1]) - 8
	if fid.Key, err = strconv.ParseUint(a[1][:index], 16, 64); err != nil {
		return
	}
	if fid.Cookie, err = strconv.ParseUint(a[1][index:], 16, 32); err != nil {
		return
	}

	return
}

// Fid in string form
func (f *Fid) String() string {
	return fmt.Sprintf("%d,%x%8x", f.Id, f.Key, f.Cookie)
}

// First, contact with master server and assign a fid, then upload to volume server
// It is same as the follow steps
// curl http://localhost:9333/dir/assign
// curl -F file=@example.jpg http://127.0.0.1:8080/3,01637037d6
func AssignUpload(filename, mimeType string, file io.Reader) (fid string, size int64, err error) {
	return defaultClient.AssignUpload(filename, mimeType, file)
}

func Delete(fid string, count int) (err error) {
	return defaultClient.Delete(fid, count)
}

func (c *Client) GetUrl(fid string) (publicUrl, url string, err error) {
	vol, err := c.Volume(fid, "")
	if err != nil {
		return
	}

	publicUrl = vol.PublicUrl + "/" + fid
	url = vol.Url + "/" + fid

	return
}

func (c *Client) AssignUpload(filename, mimeType string, file io.Reader) (fid string, size int64, err error) {

	fid, err = c.Master().Assign()
	if err != nil {
		return
	}

	vol, err := c.Volume(fid, "")
	if err != nil {
		return
	}
	size, err = vol.Upload(fid, filename, mimeType, file)

	return
}

func (c *Client) Delete(fid string, count int) (err error) {
	vol, err := c.Volume(fid, "")
	if err != nil {
		return
	}
	return vol.Delete(fid, count)
}

var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func escapeQuotes(s string) string {
	return quoteEscaper.Replace(s)
}

func createFormFile(writer *multipart.Writer, fieldname, filename, mime string) (io.Writer, error) {
	h := make(textproto.MIMEHeader)
	h.Set("Content-Disposition",
		fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
			escapeQuotes(fieldname), escapeQuotes(filename)))
	if len(mime) == 0 {
		mime = "application/octet-stream"
	}
	h.Set("Content-Type", mime)
	return writer.CreatePart(h)
}

func makeFormData(filename, mimeType string, content io.Reader) (formData io.Reader, contentType string, err error) {
	buf := new(bytes.Buffer)
	writer := multipart.NewWriter(buf)

	part, err := createFormFile(writer, "file", filename, mimeType)
	//log.Println(filename, mimeType)
	if err != nil {
		log.Println(err)
		return
	}
	_, err = io.Copy(part, content)
	if err != nil {
		log.Println(err)
		return
	}

	formData = buf
	contentType = writer.FormDataContentType()
	//log.Println(contentType)
	writer.Close()

	return
}

type uploadResp struct {
	Fid      string
	FileName string
	FileUrl  string
	Size     int64
	Error    string
}

func upload(url string, contentType string, formData io.Reader) (r *uploadResp, err error) {
	resp, err := http.Post(url, contentType, formData)
	if err != nil {
		log.Println(err)
		return
	}
	defer resp.Body.Close()

	upload := new(uploadResp)
	if err = decodeJson(resp.Body, upload); err != nil {
		return
	}

	if upload.Error != "" {
		err = errors.New(upload.Error)
		return
	}

	r = upload

	return
}

func del(url string) error {
	client := http.Client{}
	request, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return err
	}
	resp, err := client.Do(request)
	resp.Body.Close()
	return err
}

func decodeJson(r io.Reader, v interface{}) error {
	return json.NewDecoder(r).Decode(v)
}
<commit_msg>add Client.AssignUploadTK<commit_after>// weedo.go
package weedo

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/Archs/weedo/timekey"
	"io"
	"log"
	"mime/multipart"
	"net/http"
	"net/textproto"
	"os"
	"path"
	"strconv"
	"strings"
)

var defaultClient *Client

func init() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)
	defaultClient = NewClient("localhost:9333")
}

type Fid struct {
	Id, Key, Cookie uint64
}

type Client struct {
	master  *Master
	volumes map[uint64]*Volume
	filers  map[string]*Filer
}

func NewClient(masterUrl string, filerUrls ...string) *Client {
	filers := make(map[string]*Filer)
	for _, url := range filerUrls {
		filer := NewFiler(url)
		filers[filer.Url] = filer
	}
	return &Client{
		master:  NewMaster(masterUrl),
		volumes: make(map[uint64]*Volume),
		filers:  filers,
	}
}

func (c *Client) Master() *Master {
	return c.master
}

func (c *Client) Volume(volumeId, collection string) (*Volume, error) {
	vid, _ := strconv.ParseUint(volumeId, 10, 32)
	if vid == 0 {
		fid, _ := ParseFid(volumeId)
		vid = fid.Id
	}

	if vid == 0 {
		return nil, errors.New("id malformed")
	}

	if v, ok := c.volumes[vid]; ok {
		return v, nil
	}
	vol, err := c.Master().lookup(volumeId, collection)
	if err != nil {
		return nil, err
	}

	c.volumes[vid] = vol

	return vol, nil
}

func (c *Client) Filer(url string) *Filer {
	filer := NewFiler(url)
	if v, ok := c.filers[filer.Url]; ok {
		return v
	}

	c.filers[filer.Url] = filer
	return filer
}

func ParseFid(s string) (fid Fid, err error) {
	a := strings.Split(s, ",")
	if len(a) != 2 || len(a[1]) <= 8 {
		return fid, errors.New("Fid format invalid")
	}
	if fid.Id, err = strconv.ParseUint(a[0], 10, 32); err != nil {
		return
	}
	index := len(a[1]) - 8
	if fid.Key, err = strconv.ParseUint(a[1][:index], 16, 64); err != nil {
		return
	}
	if fid.Cookie, err = strconv.ParseUint(a[1][index:], 16, 32); err != nil {
		return
	}

	return
}

// Fid in string form
func (f *Fid) String() string {
	return fmt.Sprintf("%d,%x%8x", f.Id, f.Key, f.Cookie)
}

// First, contact with master server and assign a fid, then upload to volume server
// It is same as the follow steps
// curl http://localhost:9333/dir/assign
// curl -F file=@example.jpg http://127.0.0.1:8080/3,01637037d6
func AssignUpload(filename, mimeType string, file io.Reader) (fid string, size int64, err error) {
	return defaultClient.AssignUpload(filename, mimeType, file)
}

func Delete(fid string, count int) (err error) {
	return defaultClient.Delete(fid, count)
}

func (c *Client) GetUrl(fid string) (publicUrl, url string, err error) {
	vol, err := c.Volume(fid, "")
	if err != nil {
		return
	}

	publicUrl = vol.PublicUrl + "/" + fid
	url = vol.Url + "/" + fid

	return
}

func (c *Client) AssignUpload(filename, mimeType string, file io.Reader) (fid string, size int64, err error) {

	fid, err = c.Master().Assign()
	if err != nil {
		return
	}

	vol, err := c.Volume(fid, "")
	if err != nil {
		return
	}
	size, err = vol.Upload(fid, filename, mimeType, file)

	return
}

// Assign Fid using timekey.Fid
func (c *Client) AssignUploadTK(fullPath string) (fid string, err error) {
	fid, err = c.Master().Assign()
	if err != nil {
		return
	}
	tkfid, err := timekey.ParseFid(fid)
	if err != nil {
		return
	}
	// insert self defined key using timekey
	err = tkfid.InsertKeyAndCookie(fullPath)
	if err != nil {
		return
	}
	fid = tkfid.String()
	// find vold
	vol, err := c.Volume(fid, "")
	if err != nil {
		return
	}
	// do upload
	r, err := os.Open(fullPath)
	if err != nil {
		return
	}
	defer r.Close()
	// get filename
	filename := path.Base(fullPath)
	// upload
	_, err = vol.Upload(fid, filename, tkfid.MimeType(), r)
	return
}

func (c *Client) Delete(fid string, count int) (err error) {
	vol, err := c.Volume(fid, "")
	if err != nil {
		return
	}
	return vol.Delete(fid, count)
}

var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")

func escapeQuotes(s string) string {
	return quoteEscaper.Replace(s)
}

func createFormFile(writer *multipart.Writer, fieldname, filename, mime string) (io.Writer, error) {
	h := make(textproto.MIMEHeader)
	h.Set("Content-Disposition",
		fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
			escapeQuotes(fieldname), escapeQuotes(filename)))
	if len(mime) == 0 {
		mime = "application/octet-stream"
	}
	h.Set("Content-Type", mime)
	return writer.CreatePart(h)
}

func makeFormData(filename, mimeType string, content io.Reader) (formData io.Reader, contentType string, err error) {
	buf := new(bytes.Buffer)
	writer := multipart.NewWriter(buf)

	part, err := createFormFile(writer, "file", filename, mimeType)
	//log.Println(filename, mimeType)
	if err != nil {
		log.Println(err)
		return
	}
	_, err = io.Copy(part, content)
	if err != nil {
		log.Println(err)
		return
	}

	formData = buf
	contentType = writer.FormDataContentType()
	//log.Println(contentType)
	writer.Close()

	return
}

type uploadResp struct {
	Fid      string
	FileName string
	FileUrl  string
	Size     int64
	Error    string
}

func upload(url string, contentType string, formData io.Reader) (r *uploadResp, err error) {
	resp, err := http.Post(url, contentType, formData)
	if err != nil {
		log.Println(err)
		return
	}
	defer resp.Body.Close()

	upload := new(uploadResp)
	if err = decodeJson(resp.Body, upload); err != nil {
		return
	}

	if upload.Error != "" {
		err = errors.New(upload.Error)
		return
	}

	r = upload

	return
}

func del(url string) error {
	client := http.Client{}
	request, err := http.NewRequest("DELETE", url, nil)
	if err != nil {
		return err
	}
	resp, err := client.Do(request)
	resp.Body.Close()
	return err
}

func decodeJson(r io.Reader, v interface{}) error {
	return json.NewDecoder(r).Decode(v)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

type stack []int

func (s *stack) Push(v int) {
	*s = append(*s, v)
}

func (s *stack) Pop() int {
	res := (*s)[len(*s)-1]
	*s = (*s)[:len(*s)-1]
	return res
}

//ReadEdges reads adjency list from file
func ReadEdges(path string) *[][]int {
	var file, err = os.Open(path)

	if err != nil {
		fmt.Println("Failed to open file")
		os.Exit(1)
	}

	verticesMap := make(map[int]map[int]bool)
	adjancencyMap := make(map[int][]int)
	vertices := []int{}

	graph := [][]int{}

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		//Read and split line
		lineStr := scanner.Text()
		numbers := strings.Split(lineStr, " ")

		edge := []int{}

		for _, str := range numbers {
			number, err := strconv.Atoi(str)
			if err != nil {
				continue
			}

			edge = append(edge, number)
		}

		//Init map
		if _, ok := verticesMap[edge[0]]; !ok {
			verticesMap[edge[0]] = make(map[int]bool)
			adjancencyMap[edge[0]] = []int{edge[0]}
			vertices = append(vertices, edge[0])
		}

		if _, ok := verticesMap[edge[0]][edge[1]]; !ok {
			verticesMap[edge[0]][edge[1]] = true
			adjancencyMap[edge[0]] = append(adjancencyMap[edge[0]], edge[1])
		}
	}

	for _, v := range vertices {
		graph = append(graph, adjancencyMap[v])
	}

	return &graph
}

func main() {
	graph := ReadEdges("./data/SCC.txt")
	fmt.Println("Finished reading edges")

	//common.PrintGraph(graph)

	//Map of explored nodes
	explored := make(map[int]bool)
	//Finishing times
	finishingTimes := make(map[int]int)
	//Number of processed nodes
	var numProcessed int

	//First pass on inverted graph
	dfsLoop(graph, true, &explored, &finishingTimes, &numProcessed)

	//TODO: collect finishing times

	//Second pass on the original graph
	dfsLoop(graph, false, &explored, &finishingTimes, &numProcessed)

	//common.PrintGraph(&graph)
}

func dfsLoop(graph *[][]int, inverted bool, explored *map[int]bool, finishingTimes *map[int]int, numProcessed *int) {
	for index, list := range *graph {
		i := list[0]
		//if i not yet explored
		if _, ok := (*explored)[i]; !ok {
			//TODO: assign s
			dfs(graph, index, explored, finishingTimes, numProcessed)
		}
	}
}

func dfs(graph *[][]int, index int, explored *map[int]bool, finishingTimes *map[int]int, numProcessed *int) {
	//Restore list from dfsLoop
	list := (*graph)[index]
	i := list[0]

	return

	//Mark i as explored
	(*explored)[i] = true

	//for each (i, j) from G ...
	for _, j := range list {
		if j == i {
			continue
		}

		//if j not yet explored
		if _, ok := (*explored)[j]; !ok {
			indexOfJsVertex := j
			dfs(graph, indexOfJsVertex, explored, finishingTimes, numProcessed)
		}
	}
	(*numProcessed)++
	(*finishingTimes)[i] = *numProcessed
}
<commit_msg>Backward edges<commit_after>package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

type stack []int

func (s *stack) Push(v int) {
	*s = append(*s, v)
}

func (s *stack) Pop() int {
	res := (*s)[len(*s)-1]
	*s = (*s)[:len(*s)-1]
	return res
}

//ReadEdges reads adjency list from file and returns (adjency list, vertex index) pair
func ReadEdges(path string) (*[][]int, *map[int]int) {
	var file, err = os.Open(path)

	if err != nil {
		fmt.Println("Failed to open file")
		os.Exit(1)
	}

	verticesIndex := make(map[int]int)
	adjacencyMap := make(map[int][]int)
	vertices := []int{}

	graph := [][]int{}

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		//Read and split line
		lineStr := scanner.Text()
		numbers := strings.Split(lineStr, " ")

		edge := []int{}

		for _, str := range numbers {
			number, err := strconv.Atoi(str)
			if err != nil {
				continue
			}

			edge = append(edge, number)
		}

		addVertex(edge[0], &verticesIndex, &adjacencyMap, &vertices)
		addVertex(edge[1], &verticesIndex, &adjacencyMap, &vertices)

		adjacencyMap[edge[0]] = append(adjacencyMap[edge[0]], edge[1])
		if edge[0] != edge[1] {
			adjacencyMap[edge[1]] = append(adjacencyMap[edge[1]], -edge[0])
		}
	}

	for _, v := range vertices {
		graph = append(graph, adjacencyMap[v])
	}

	return &graph, &verticesIndex
}

func addVertex(v int, verticesIndex *map[int]int, adjacencyMap *map[int][]int, vertices *[]int) {
	//Init map for edge tail
	if _, ok := (*verticesIndex)[v]; !ok {
		(*verticesIndex)[v] = len(*vertices)
		(*adjacencyMap)[v] = []int{v}
		*vertices = append(*vertices, v)
	}
}

func main() {
	graph, verticesIndex := ReadEdges("./data/SCC.txt")
	fmt.Println("Finished reading edges")
	fmt.Printf("vertex[1]: %v\n", (*graph)[(*verticesIndex)[1]][0:30])
	fmt.Printf("vertex[5]: %v\n", (*graph)[(*verticesIndex)[5]][0:30])
	fmt.Printf("vertex[6]: %v\n", (*graph)[(*verticesIndex)[6]][0:10])
	//common.PrintGraph(graph)

	//Map of explored nodes
	explored := make(map[int]bool)
	//Finishing times
	finishingTimes := make(map[int]int)
	//Number of processed nodes
	var numProcessed int

	//First pass on inverted graph
	dfsLoop(graph, true, &explored, &finishingTimes, &numProcessed)

	//TODO: collect finishing times

	//Second pass on the original graph
	dfsLoop(graph, false, &explored, &finishingTimes, &numProcessed)

	//common.PrintGraph(&graph)
}

func dfsLoop(graph *[][]int, inverted bool, explored *map[int]bool, finishingTimes *map[int]int, numProcessed *int) {
	for index, list := range *graph {
		i := list[0]
		//if i not yet explored
		if _, ok := (*explored)[i]; !ok {
			//TODO: assign s
			dfs(graph, index, explored, finishingTimes, numProcessed)
		}
	}
}

func dfs(graph *[][]int, index int, explored *map[int]bool, finishingTimes *map[int]int, numProcessed *int) {
	//Restore list from dfsLoop
	list := (*graph)[index]
	i := list[0]

	return

	//Mark i as explored
	(*explored)[i] = true

	//for each (i, j) from G ...
	for _, j := range list {
		if j == i {
			continue
		}

		//if j not yet explored
		if _, ok := (*explored)[j]; !ok {
			indexOfJsVertex := j
			dfs(graph, indexOfJsVertex, explored, finishingTimes, numProcessed)
		}
	}
	(*numProcessed)++
	(*finishingTimes)[i] = *numProcessed
}
<|endoftext|>


<commit_before>// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	"encoding/json"
	"net/http"
)

// Network represents a network.
type Network struct {
	Name      string `json:"name"`
	ID        string `json:"id"`
	Type      string `json:"type"`
	Endpoints []struct {
		Name    string `json:"name"`
		ID      string `json:"id"`
		Network string `json:"network"`
	} `json:"endpoints"`
}

// ListNetworks returns all networks.
func (c *Client) ListNetworks() ([]Network, error) {
	path := "/networks"
	body, _, err := c.do("GET", path, doOptions{})
	if err != nil {
		return nil, err
	}
	var networks []Network
	if err := json.Unmarshal(body, &networks); err != nil {
		return nil, err
	}
	return networks, nil
}

// NetworkInfo returns information about a network by its ID.
func (c *Client) NetworkInfo(id string) (*Network, error) {
	path := "/networks/" + id
	body, status, err := c.do("GET", path, doOptions{})
	if status == http.StatusNotFound {
		return nil, &NoSuchNetwork{ID: path}
	}
	if err != nil {
		return nil, err
	}
	var network Network
	if err := json.Unmarshal(body, &network); err != nil {
		return nil, err
	}
	return &network, nil
}

// NoSuchNetwork is the error returned when a given network does not exist.
type NoSuchNetwork struct {
	ID string
}

func (err *NoSuchNetwork) Error() string {
	return fmt.Sprintf("No such network: %s", err.ID)
}
<commit_msg>fixup!<commit_after>// Copyright 2015 go-dockerclient authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package docker

import (
	"encoding/json"
	"fmt"
	"net/http"
)

// Network represents a network.
type Network struct {
	Name      string `json:"name"`
	ID        string `json:"id"`
	Type      string `json:"type"`
	Endpoints []struct {
		Name    string `json:"name"`
		ID      string `json:"id"`
		Network string `json:"network"`
	} `json:"endpoints"`
}

// ListNetworks returns all networks.
func (c *Client) ListNetworks() ([]Network, error) {
	path := "/networks"
	body, _, err := c.do("GET", path, doOptions{})
	if err != nil {
		return nil, err
	}
	var networks []Network
	if err := json.Unmarshal(body, &networks); err != nil {
		return nil, err
	}
	return networks, nil
}

// NetworkInfo returns information about a network by its ID.
func (c *Client) NetworkInfo(id string) (*Network, error) {
	path := "/networks/" + id
	body, status, err := c.do("GET", path, doOptions{})
	if status == http.StatusNotFound {
		return nil, &NoSuchNetwork{ID: path}
	}
	if err != nil {
		return nil, err
	}
	var network Network
	if err := json.Unmarshal(body, &network); err != nil {
		return nil, err
	}
	return &network, nil
}

// NoSuchNetwork is the error returned when a given network does not exist.
type NoSuchNetwork struct {
	ID string
}

func (err *NoSuchNetwork) Error() string {
	return fmt.Sprintf("No such network: %s", err.ID)
}
<|endoftext|>


<commit_before>package fonet

import (
	"errors"
	"log"
	"math"
	"math/rand"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

// Network is containing all the needed settings/variables.
type Network struct {
	w      [][][]float64           // weights
	b      [][]float64             // biases
	d      [][]float64             // delta values for
	z      [][]float64             // z values in each layer
	l      int                     // Number of the layers
	ls     []int                   // number of the neurons in each layer
	aFunc  func(z float64) float64 // activation function
	daFunc func(z float64) float64 // derivative of the aFunc
}

func sigmoid(z float64) float64 {
	return 1. / (1. + math.Exp(-z))
}

func sigmoidD(z float64) float64 {
	return sigmoid(z) * (1 - sigmoid(z))
}

// NewNetwork is for creating a new network
// with the defined layers.
func NewNetwork(ls []int) (*Network, error) {
	if len(ls) < 3 {
		return nil, errors.New("Not enough layer in the layers description")
	}
	n := Network{
		l:      len(ls) - 1,
		ls:     ls[1:],
		aFunc:  sigmoid,
		daFunc: sigmoidD,
	}

	// init weights
	n.w = make([][][]float64, n.l)
	n.w[0] = make([][]float64, ls[0])
	for i := 0; i < ls[0]; i++ {
		n.w[0][i] = make([]float64, n.ls[0])
		for j := 0; j < n.ls[0]; j++ {
			n.w[0][i][j] = rand.Float64()
		}
	}
	for l := 1; l < n.l; l++ {
		n.w[l] = make([][]float64, n.ls[l-1])
		for i := 0; i < n.ls[l-1]; i++ {
			n.w[l][i] = make([]float64, n.ls[l])
			for j := 0; j < n.ls[l]; j++ {
				n.w[l][i][j] = rand.Float64()
			}
		}
	}

	// init biases, deltas, z(s)
	n.b = make([][]float64, n.l)
	n.d = make([][]float64, n.l)
	n.z = make([][]float64, n.l)
	for l := 0; l < n.l; l++ {
		n.b[l] = make([]float64, n.ls[l])
		for i := 0; i < n.ls[l]; i++ {
			n.b[l][i] = rand.Float64()
		}
		n.d[l] = make([]float64, n.ls[l])
		n.z[l] = make([]float64, n.ls[l])
	}

	return &n, nil
}

func (n *Network) dw(l, i, j int, eta float64) float64 {
	return -eta * n.d[l][j] * n.a(l-1, i)
}

func (n *Network) a(l, j int) float64 {
	return n.aFunc(n.z[l][j])
}

// Train is for training the network with the specified dataset,
// epoch and learning rate
// The last bool parameter is for tracking where the training is. It'll log each epoch.
func (n *Network) Train(trainingData [][][]float64, epochs int, lrate float64, debug bool) {
	for e := 0; e < epochs; e++ {
		for _, xy := range trainingData {
			n.backpropagate(xy, lrate)
		}
		if debug {
			log.Println("Epoch:", e+1, "/", epochs)
		}
	}
}

func (n *Network) backpropagate(xy [][]float64, eta float64) {
	x := xy[0]
	y := xy[1]
	_ = n.feedforward(x) // define z values

	// define the output deltas
	for j := 0; j < len(n.d[len(n.d)-1]); j++ {
		n.d[len(n.d)-1][j] = (n.a(len(n.d)-1, j) - y[j]) * n.daFunc(n.z[len(n.d)-1][j])
	}

	// define the inner deltas
	for l := len(n.d) - 2; l >= 0; l-- {
		for j := 0; j < len(n.d[l]); j++ {
			n.d[l][j] = n.delta(l, j)
		}
	}

	// update weights
	for i := 0; i < len(n.w[0]); i++ {
		for j := 0; j < len(n.w[0][i]); j++ {
			n.w[0][i][j] += -eta * n.d[0][j] * x[i]
		}
	}
	for l := 1; l < len(n.w); l++ {
		for i := 0; i < len(n.w[l]); i++ {
			for j := 0; j < len(n.w[l][i]); j++ {
				n.w[l][i][j] += n.dw(l, i, j, eta)
			}
		}
	}

	// update biases
	for l := 0; l < len(n.b); l++ {
		for j := 0; j < len(n.b[l]); j++ {
			n.b[l][j] += -eta * n.d[l][j]
		}
	}
}

// use only in the backpropagation! othervise it can return wrong value
func (n *Network) delta(l, j int) float64 {
	var d float64
	for k := 0; k < n.ls[l+1]; k++ {
		d += n.d[l+1][k] * n.w[l+1][j][k] * n.daFunc(n.z[l][j])
	}
	return d
}

func (n *Network) feedforward(a []float64) []float64 {
	for l := 0; l < n.l; l++ {
		atemp := make([]float64, n.ls[l])
		for j := 0; j < n.ls[l]; j++ {
			n.z[l][j] = 0
			for i := 0; i < len(a); i++ {
				n.z[l][j] += n.w[l][i][j] * a[i]
			}
			n.z[l][j] += n.b[l][j]
			atemp[j] = n.aFunc(n.z[l][j])
		}
		a = atemp
	}
	return a
}

// Predict calculates the output for the given input
func (n *Network) Predict(input []float64) []float64 {
	return n.feedforward(input)
}
<commit_msg>Added Export and Load to/from json<commit_after>package fonet

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"math"
	"math/rand"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

// Network is containing all the needed settings/variables.
type Network struct {
	w      [][][]float64           // weights
	b      [][]float64             // biases
	d      [][]float64             // delta values for
	z      [][]float64             // z values in each layer
	l      int                     // Number of the layers
	ls     []int                   // number of the neurons in each layer
	aFunc  func(z float64) float64 // activation function
	daFunc func(z float64) float64 // derivative of the aFunc
}

func sigmoid(z float64) float64 {
	return 1. / (1. + math.Exp(-z))
}

func sigmoidD(z float64) float64 {
	return sigmoid(z) * (1 - sigmoid(z))
}

// NewNetwork is for creating a new network
// with the defined layers.
func NewNetwork(ls []int) (*Network, error) {
	if len(ls) < 3 {
		return nil, errors.New("Not enough layer in the layers description")
	}
	n := Network{
		l:      len(ls) - 1,
		ls:     ls[1:],
		aFunc:  sigmoid,
		daFunc: sigmoidD,
	}

	// init weights
	n.w = make([][][]float64, n.l)
	n.w[0] = make([][]float64, ls[0])
	for i := 0; i < ls[0]; i++ {
		n.w[0][i] = make([]float64, n.ls[0])
		for j := 0; j < n.ls[0]; j++ {
			n.w[0][i][j] = rand.Float64()
		}
	}
	for l := 1; l < n.l; l++ {
		n.w[l] = make([][]float64, n.ls[l-1])
		for i := 0; i < n.ls[l-1]; i++ {
			n.w[l][i] = make([]float64, n.ls[l])
			for j := 0; j < n.ls[l]; j++ {
				n.w[l][i][j] = rand.Float64()
			}
		}
	}

	// init biases, deltas, z(s)
	n.b = make([][]float64, n.l)
	n.d = make([][]float64, n.l)
	n.z = make([][]float64, n.l)
	for l := 0; l < n.l; l++ {
		n.b[l] = make([]float64, n.ls[l])
		for i := 0; i < n.ls[l]; i++ {
			n.b[l][i] = rand.Float64()
		}
		n.d[l] = make([]float64, n.ls[l])
		n.z[l] = make([]float64, n.ls[l])
	}

	return &n, nil
}

func (n *Network) dw(l, i, j int, eta float64) float64 {
	return -eta * n.d[l][j] * n.a(l-1, i)
}

func (n *Network) a(l, j int) float64 {
	return n.aFunc(n.z[l][j])
}

// Train is for training the network with the specified dataset,
// epoch and learning rate
// The last bool parameter is for tracking where the training is. It'll log each epoch.
func (n *Network) Train(trainingData [][][]float64, epochs int, lrate float64, debug bool) {
	for e := 0; e < epochs; e++ {
		for _, xy := range trainingData {
			n.backpropagate(xy, lrate)
		}
		if debug {
			log.Println("Epoch:", e+1, "/", epochs)
		}
	}
}

func (n *Network) backpropagate(xy [][]float64, eta float64) {
	x := xy[0]
	y := xy[1]
	_ = n.feedforward(x) // define z values

	// define the output deltas
	for j := 0; j < len(n.d[len(n.d)-1]); j++ {
		n.d[len(n.d)-1][j] = (n.a(len(n.d)-1, j) - y[j]) * n.daFunc(n.z[len(n.d)-1][j])
	}

	// define the inner deltas
	for l := len(n.d) - 2; l >= 0; l-- {
		for j := 0; j < len(n.d[l]); j++ {
			n.d[l][j] = n.delta(l, j)
		}
	}

	// update weights
	for i := 0; i < len(n.w[0]); i++ {
		for j := 0; j < len(n.w[0][i]); j++ {
			n.w[0][i][j] += -eta * n.d[0][j] * x[i]
		}
	}
	for l := 1; l < len(n.w); l++ {
		for i := 0; i < len(n.w[l]); i++ {
			for j := 0; j < len(n.w[l][i]); j++ {
				n.w[l][i][j] += n.dw(l, i, j, eta)
			}
		}
	}

	// update biases
	for l := 0; l < len(n.b); l++ {
		for j := 0; j < len(n.b[l]); j++ {
			n.b[l][j] += -eta * n.d[l][j]
		}
	}
}

// use only in the backpropagation! othervise it can return wrong value
func (n *Network) delta(l, j int) float64 {
	var d float64
	for k := 0; k < n.ls[l+1]; k++ {
		d += n.d[l+1][k] * n.w[l+1][j][k] * n.daFunc(n.z[l][j])
	}
	return d
}

func (n *Network) feedforward(a []float64) []float64 {
	for l := 0; l < n.l; l++ {
		atemp := make([]float64, n.ls[l])
		for j := 0; j < n.ls[l]; j++ {
			n.z[l][j] = 0
			for i := 0; i < len(a); i++ {
				n.z[l][j] += n.w[l][i][j] * a[i]
			}
			n.z[l][j] += n.b[l][j]
			atemp[j] = n.aFunc(n.z[l][j])
		}
		a = atemp
	}
	return a
}

// Predict calculates the output for the given input
func (n *Network) Predict(input []float64) []float64 {
	return n.feedforward(input)
}

type exportedNet struct {
	W  [][][]float64 // weights
	B  [][]float64   // biases
	D  [][]float64   // delta values for
	Z  [][]float64   // z values in each layer
	L  int           // Number of the layers
	LS []int         // number of the neurons in each layer
}

func (n *Network) Export(w io.Writer) error {
	bs, err := json.Marshal(exportedNet{
		W:  n.w,
		B:  n.b,
		D:  n.d,
		Z:  n.z,
		L:  n.l,
		LS: n.ls,
	})
	if err != nil {
		return err
	}
	fmt.Fprint(w, string(bs))
	return nil
}

func Load(bs []byte) (*Network, error) {
	var en exportedNet
	err := json.Unmarshal(bs, &en)
	if err != nil {
		return nil, err
	}
	return &Network{
		w:      en.W,
		b:      en.B,
		d:      en.D,
		z:      en.Z,
		l:      en.L,
		ls:     en.LS,
		aFunc:  sigmoid,
		daFunc: sigmoidD,
	}, nil
}
<|endoftext|>


<commit_before>// checkpoint is a package for checking version information and alerts
// for a HashiCorp product.
package checkpoint

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"runtime"
)

// CheckParams are the parameters for configuring a check request.
type CheckParams struct {
	// Product and version are used to lookup the correct product and
	// alerts for the proper version. The version is also used to perform
	// a version check.
	Product string
	Version string

	// Arch and OS are used to filter alerts potentially only to things
	// affecting a specific os/arch combination. If these aren't specified,
	// they'll be automatically filled in.
	Arch string
	OS   string

	// Signature is some random signature that should be stored and used
	// as a cookie-like value. This ensures that alerts aren't repeated.
	// If the signature is changed, repeat alerts may be sent down. The
	// signature should NOT be anything identifiable to a user (such as
	// a MAC address). It should be random.
	Signature string
}

// CheckResponse is the response for a check request.
type CheckResponse struct {
	Product             string
	CurrentVersion      string `json:"current_version"`
	CurrentReleaseDate  int    `json:"current_release_date"`
	CurrentDownloadURL  string `json:"current_download_url"`
	CurrentChangelogURL string `json:"current_changelog_url"`
	ProjectWebsite      string `json:"project_website"`
	Outdated            bool   `json:"outdated"`
	Alerts              []*CheckAlert
}

// CheckAlert is a single alert message from a check request.
//
// These never have to be manually constructed, and are typically populated
// into a CheckResponse as a result of the Check request.
type CheckAlert struct {
	ID      int
	Date    int
	Message string
	URL     string
	Level   string
}

// Check checks for alerts and new version information.
func Check(p *CheckParams) (*CheckResponse, error) {
	var u url.URL

	if p.Arch == "" {
		p.Arch = runtime.GOARCH
	}
	if p.OS == "" {
		p.OS = runtime.GOOS
	}

	v := u.Query()
	v.Set("version", p.Version)
	v.Set("arch", p.Arch)
	v.Set("os", p.OS)
	v.Set("signature", p.Signature)

	u.Scheme = "http"
	u.Host = "api.checkpoint.hashicorp.com"
	u.Path = fmt.Sprintf("/v1/check/%s", p.Product)
	u.RawQuery = v.Encode()

	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Accept", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Unknown status: %d", resp.StatusCode)
	}

	var result CheckResponse
	dec := json.NewDecoder(resp.Body)
	if err := dec.Decode(&result); err != nil {
		return nil, err
	}

	return &result, nil
}
<commit_msg>SignatureFile<commit_after>// checkpoint is a package for checking version information and alerts
// for a HashiCorp product.
package checkpoint

import (
	"crypto/rand"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"runtime"
	"strings"
)

// CheckParams are the parameters for configuring a check request.
type CheckParams struct {
	// Product and version are used to lookup the correct product and
	// alerts for the proper version. The version is also used to perform
	// a version check.
	Product string
	Version string

	// Arch and OS are used to filter alerts potentially only to things
	// affecting a specific os/arch combination. If these aren't specified,
	// they'll be automatically filled in.
	Arch string
	OS   string

	// Signature is some random signature that should be stored and used
	// as a cookie-like value. This ensures that alerts aren't repeated.
	// If the signature is changed, repeat alerts may be sent down. The
	// signature should NOT be anything identifiable to a user (such as
	// a MAC address). It should be random.
	//
	// If SignatureFile is given, then the signature will be read from this
	// file. If the file doesn't exist, then a random signature will
	// automatically be generated and stored here. SignatureFile will be
	// ignored if Signature is given.
	Signature     string
	SignatureFile string
}

// CheckResponse is the response for a check request.
type CheckResponse struct {
	Product             string
	CurrentVersion      string `json:"current_version"`
	CurrentReleaseDate  int    `json:"current_release_date"`
	CurrentDownloadURL  string `json:"current_download_url"`
	CurrentChangelogURL string `json:"current_changelog_url"`
	ProjectWebsite      string `json:"project_website"`
	Outdated            bool   `json:"outdated"`
	Alerts              []*CheckAlert
}

// CheckAlert is a single alert message from a check request.
//
// These never have to be manually constructed, and are typically populated
// into a CheckResponse as a result of the Check request.
type CheckAlert struct {
	ID      int
	Date    int
	Message string
	URL     string
	Level   string
}

// Check checks for alerts and new version information.
func Check(p *CheckParams) (*CheckResponse, error) {
	var u url.URL

	if p.Arch == "" {
		p.Arch = runtime.GOARCH
	}
	if p.OS == "" {
		p.OS = runtime.GOOS
	}

	// If we're given a SignatureFile, then attempt to read that.
	signature := p.Signature
	if p.Signature == "" && p.SignatureFile != "" {
		if _, err := os.Stat(p.SignatureFile); err != nil {
			// If this isn't a non-exist error, then return that.
			if !os.IsNotExist(err) {
				return nil, err
			}

			// The file doesn't exist, so create a signature.
			var b [16]byte
			n := 0
			for n < 16 {
				n2, err := rand.Read(b[n:])
				if err != nil {
					return nil, err
				}

				n += n2
			}
			signature = fmt.Sprintf(
				"%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])

			// Write the signature
			err := ioutil.WriteFile(p.SignatureFile, []byte(signature+"\n"), 0644)
			if err != nil {
				return nil, err
			}
		} else {
			// The file exists, read it out
			sigBytes, err := ioutil.ReadFile(p.SignatureFile)
			if err != nil {
				return nil, err
			}

			signature = strings.TrimSpace(string(sigBytes))
		}
	}

	v := u.Query()
	v.Set("version", p.Version)
	v.Set("arch", p.Arch)
	v.Set("os", p.OS)
	v.Set("signature", signature)

	u.Scheme = "http"
	u.Host = "api.checkpoint.hashicorp.com"
	u.Path = fmt.Sprintf("/v1/check/%s", p.Product)
	u.RawQuery = v.Encode()

	req, err := http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return nil, err
	}
	req.Header.Add("Accept", "application/json")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("Unknown status: %d", resp.StatusCode)
	}

	var result CheckResponse
	dec := json.NewDecoder(resp.Body)
	if err := dec.Decode(&result); err != nil {
		return nil, err
	}

	return &result, nil
}
<|endoftext|>


<commit_before>/*
 * gomacro - A Go interpreter with Lisp-like macros
 *
 * Copyright (C) 2017-2018 Massimiliano Ghilardi
 *
 *     This Source Code Form is subject to the terms of the Mozilla Public
 *     License, v. 2.0. If a copy of the MPL was not distributed with this
 *     file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *
 * paths.go
 *
 *  Created on: Jun 24, 2018
 *      Author: Massimiliano Ghilardi
 */

package paths

import (
	"go/build"
	"os"
	"strings"
)

// return the string after last '/' in path
func FileName(path string) string {
	return path[1+strings.LastIndexByte(path, '/'):]
}

// return the string up to (and including) last '/' in path
func DirName(path string) string {
	return path[0 : 1+strings.LastIndexByte(path, '/')]
}

// remove last byte from string
func RemoveLastByte(s string) string {
	if n := len(s); n != 0 {
		s = s[:n-1]
	}
	return s
}

// always use forward slashes. they work also on Windows...
func unixpath(path string) string {
	if os.PathSeparator != '/' && len(path) != 0 {
		path = strings.Replace(path, string(os.PathSeparator), "/", -1)
	}
	return path
}

// find user's home directory, see https://stackoverflow.com/questions/2552416/how-can-i-find-the-users-home-dir-in-a-cross-platform-manner-using-c
// without importing "os/user" - which requires cgo to work thus makes cross-compile difficult, see https://github.com/golang/go/issues/11797
func UserHomeDir() string {
	home := os.Getenv("HOME")
	if len(home) == 0 {
		home = os.Getenv("USERPROFILE")
		if len(home) == 0 {
			home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
		}
	}
	return unixpath(home)
}

func Subdir(dirs ...string) string {
	// should use string(os.PathSeparator) instead of "/', but:
	// 1) package names use '/', not os.PathSeparator
	// 2) it would complicate DirName()
	return strings.Join(dirs, "/")
}

var (
	GoSrcDir = Subdir(build.Default.GOPATH, "src")

	GomacroDir = Subdir(GoSrcDir, "github.com", "cosmos72", "gomacro") // vendored copies of gomacro may need to change this
)
<commit_msg>Handle list of directories in $GOPATH<commit_after>/*
 * gomacro - A Go interpreter with Lisp-like macros
 *
 * Copyright (C) 2017-2018 Massimiliano Ghilardi
 *
 *     This Source Code Form is subject to the terms of the Mozilla Public
 *     License, v. 2.0. If a copy of the MPL was not distributed with this
 *     file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *
 * paths.go
 *
 *  Created on: Jun 24, 2018
 *      Author: Massimiliano Ghilardi
 */

package paths

import (
	"fmt"
	"go/build"
	"os"
	"path/filepath"
	"strings"
)

// return the string after last '/' in path
func FileName(path string) string {
	return path[1+strings.LastIndexByte(path, '/'):]
}

// return the string up to (and including) last '/' in path
func DirName(path string) string {
	return path[0 : 1+strings.LastIndexByte(path, '/')]
}

// remove last byte from string
func RemoveLastByte(s string) string {
	if n := len(s); n != 0 {
		s = s[:n-1]
	}
	return s
}

// always use forward slashes. they work also on Windows...
func unixpath(path string) string {
	if os.PathSeparator != '/' && len(path) != 0 {
		path = strings.Replace(path, string(os.PathSeparator), "/", -1)
	}
	return path
}

// find user's home directory, see https://stackoverflow.com/questions/2552416/how-can-i-find-the-users-home-dir-in-a-cross-platform-manner-using-c
// without importing "os/user" - which requires cgo to work thus makes cross-compile difficult, see https://github.com/golang/go/issues/11797
func UserHomeDir() string {
	home := os.Getenv("HOME")
	if len(home) == 0 {
		home = os.Getenv("USERPROFILE")
		if len(home) == 0 {
			home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
		}
	}
	return unixpath(home)
}

func Subdir(dirs ...string) string {
	// should use string(os.PathSeparator) instead of "/', but:
	// 1) package names use '/', not os.PathSeparator
	// 2) it would complicate DirName()
	return strings.Join(dirs, "/")
}

func findGomacroDir() string {
	pkg := filepath.Join("github.com", "cosmos72", "gomacro") // vendored copies of gomacro may need to change this
	for _, dir := range filepath.SplitList(build.Default.GOPATH) {
		path := filepath.Join(dir, "src", pkg)
		if _, err := os.Stat(path); err == nil {
			return path
		}
	}
	fmt.Printf("// WARNING: could not find %q in $GOPATH\n", pkg)
	return GoSrcDir
}

var (
	GoSrcDir = Subdir(filepath.SplitList(build.Default.GOPATH)[0], "src")

	GomacroDir = findGomacroDir()
)
<|endoftext|>


<commit_before>package chord

import (
	"runtime"
	"testing"
	"time"
)

func TestDefaultConfig(t *testing.T) {
	conf := DefaultConfig("test")
	if conf.Hostname != "test" {
		t.Fatalf("bad hostname")
	}
	if conf.NumVnodes != 8 {
		t.Fatalf("bad num vnodes")
	}
	if conf.NumSuccessors != 8 {
		t.Fatalf("bad num succ")
	}
	if conf.HashFunc == nil {
		t.Fatalf("bad hash")
	}
	if conf.HashBits != 160 {
		t.Fatalf("bad hash bits")
	}
	if conf.StabilizeMin != time.Duration(15*time.Second) {
		t.Fatalf("bad min stable")
	}
	if conf.StabilizeMax != time.Duration(45*time.Second) {
		t.Fatalf("bad max stable")
	}
	if conf.Delegate != nil {
		t.Fatalf("bad delegate")
	}
}

func fastConf() *Config {
	conf := DefaultConfig("test")
	conf.StabilizeMin = time.Duration(15 * time.Millisecond)
	conf.StabilizeMax = time.Duration(45 * time.Millisecond)
	return conf
}

func TestCreateShutdown(t *testing.T) {
	// Start the timer thread
	time.After(15)
	conf := fastConf()
	numGo := runtime.NumGoroutine()
	r, err := Create(conf, nil)
	if err != nil {
		t.Fatalf("unexpected err. %s", err)
	}
	r.Shutdown()
	after := runtime.NumGoroutine()
	if after != numGo {
		t.Fatalf("unexpected routines! A:%d B:%d", after, numGo)
	}
}
<commit_msg>Test the Chord methods<commit_after>package chord

import (
	"runtime"
	"testing"
	"time"
)

type MultiLocalTrans struct {
	remote Transport
	hosts  map[string]*LocalTransport
}

func InitMLTransport() *MultiLocalTrans {
	hosts := make(map[string]*LocalTransport)
	remote := &BlackholeTransport{}
	ml := &MultiLocalTrans{hosts: hosts}
	ml.remote = remote
	return ml
}

func (ml *MultiLocalTrans) ListVnodes(host string) ([]*Vnode, error) {
	if local, ok := ml.hosts[host]; ok {
		return local.ListVnodes(host)
	}
	return ml.remote.ListVnodes(host)
}

// Ping a Vnode, check for liveness
func (ml *MultiLocalTrans) Ping(v *Vnode) (bool, error) {
	if local, ok := ml.hosts[v.Host]; ok {
		return local.Ping(v)
	}
	return ml.remote.Ping(v)
}

// Request a nodes predecessor
func (ml *MultiLocalTrans) GetPredecessor(v *Vnode) (*Vnode, error) {
	if local, ok := ml.hosts[v.Host]; ok {
		return local.GetPredecessor(v)
	}
	return ml.remote.GetPredecessor(v)
}

// Notify our successor of ourselves
func (ml *MultiLocalTrans) Notify(target, self *Vnode) ([]*Vnode, error) {
	if local, ok := ml.hosts[target.Host]; ok {
		return local.Notify(target, self)
	}
	return ml.remote.Notify(target, self)
}

// Find a successor
func (ml *MultiLocalTrans) FindSuccessors(v *Vnode, n int, k []byte) ([]*Vnode, error) {
	if local, ok := ml.hosts[v.Host]; ok {
		return local.FindSuccessors(v, n, k)
	}
	return ml.remote.FindSuccessors(v, n, k)
}

// Clears a predecessor if it matches a given vnode. Used to leave.
func (ml *MultiLocalTrans) ClearPredecessor(target, self *Vnode) error {
	if local, ok := ml.hosts[target.Host]; ok {
		return local.ClearPredecessor(target, self)
	}
	return ml.remote.ClearPredecessor(target, self)
}

// Instructs a node to skip a given successor. Used to leave.
func (ml *MultiLocalTrans) SkipSuccessor(target, self *Vnode) error {
	if local, ok := ml.hosts[target.Host]; ok {
		return local.SkipSuccessor(target, self)
	}
	return ml.remote.SkipSuccessor(target, self)
}

func (ml *MultiLocalTrans) Register(v *Vnode, o VnodeRPC) {
	local, ok := ml.hosts[v.Host]
	if !ok {
		local = InitLocalTransport(nil).(*LocalTransport)
		ml.hosts[v.Host] = local
	}
	local.Register(v, o)
}

func (ml *MultiLocalTrans) Deregister(host string) {
	delete(ml.hosts, host)
}

func TestDefaultConfig(t *testing.T) {
	conf := DefaultConfig("test")
	if conf.Hostname != "test" {
		t.Fatalf("bad hostname")
	}
	if conf.NumVnodes != 8 {
		t.Fatalf("bad num vnodes")
	}
	if conf.NumSuccessors != 8 {
		t.Fatalf("bad num succ")
	}
	if conf.HashFunc == nil {
		t.Fatalf("bad hash")
	}
	if conf.HashBits != 160 {
		t.Fatalf("bad hash bits")
	}
	if conf.StabilizeMin != time.Duration(15*time.Second) {
		t.Fatalf("bad min stable")
	}
	if conf.StabilizeMax != time.Duration(45*time.Second) {
		t.Fatalf("bad max stable")
	}
	if conf.Delegate != nil {
		t.Fatalf("bad delegate")
	}
}

func fastConf() *Config {
	conf := DefaultConfig("test")
	conf.StabilizeMin = time.Duration(15 * time.Millisecond)
	conf.StabilizeMax = time.Duration(45 * time.Millisecond)
	return conf
}

func TestCreateShutdown(t *testing.T) {
	// Start the timer thread
	time.After(15)
	conf := fastConf()
	numGo := runtime.NumGoroutine()
	r, err := Create(conf, nil)
	if err != nil {
		t.Fatalf("unexpected err. %s", err)
	}
	r.Shutdown()
	after := runtime.NumGoroutine()
	if after != numGo {
		t.Fatalf("unexpected routines! A:%d B:%d", after, numGo)
	}
}

func TestJoin(t *testing.T) {
	// Create a multi transport
	ml := InitMLTransport()

	// Create the initial ring
	conf := fastConf()
	r, err := Create(conf, ml)
	if err != nil {
		t.Fatalf("unexpected err. %s", err)
	}

	// Create a second ring
	conf2 := fastConf()
	conf2.Hostname = "test2"
	r2, err := Join(conf2, ml, "test")
	if err != nil {
		t.Fatalf("failed to join local node! Got %s", err)
	}

	// Shutdown
	r.Shutdown()
	r2.Shutdown()
}

func TestJoinDeadHost(t *testing.T) {
	// Create a multi transport
	ml := InitMLTransport()

	// Create the initial ring
	conf := fastConf()
	_, err := Join(conf, ml, "noop")
	if err == nil {
		t.Fatalf("expected err!")
	}
}

func TestLeave(t *testing.T) {
	// Create a multi transport
	ml := InitMLTransport()

	// Create the initial ring
	conf := fastConf()
	r, err := Create(conf, ml)
	if err != nil {
		t.Fatalf("unexpected err. %s", err)
	}

	// Create a second ring
	conf2 := fastConf()
	conf2.Hostname = "test2"
	r2, err := Join(conf2, ml, "test")
	if err != nil {
		t.Fatalf("failed to join local node! Got %s", err)
	}

	// Wait for some stabilization
	<-time.After(100 * time.Millisecond)

	// Node 1 should leave
	r.Leave()
	ml.Deregister("test")

	// Wait for stabilization
	<-time.After(100 * time.Millisecond)

	// Verify r2 ring is still in tact
	num := len(r2.vnodes)
	for idx, vn := range r2.vnodes {
		if vn.successors[0] != &r2.vnodes[(idx+1)%num].Vnode {
			t.Fatalf("bad successor! Got:%s:%s", vn.successors[0].Host,
				vn.successors[0])
		}
	}
}

func TestLookupBadN(t *testing.T) {
	// Create a multi transport
	ml := InitMLTransport()

	// Create the initial ring
	conf := fastConf()
	r, err := Create(conf, ml)
	if err != nil {
		t.Fatalf("unexpected err. %s", err)
	}

	_, err = r.Lookup(10, []byte("test"))
	if err == nil {
		t.Fatalf("expected err!")
	}
}

func TestLookup(t *testing.T) {
	// Create a multi transport
	ml := InitMLTransport()

	// Create the initial ring
	conf := fastConf()
	r, err := Create(conf, ml)
	if err != nil {
		t.Fatalf("unexpected err. %s", err)
	}

	// Create a second ring
	conf2 := fastConf()
	conf2.Hostname = "test2"
	r2, err := Join(conf2, ml, "test")
	if err != nil {
		t.Fatalf("failed to join local node! Got %s", err)
	}

	// Wait for some stabilization
	<-time.After(100 * time.Millisecond)

	// Try key lookup
	keys := [][]byte{[]byte("test"), []byte("foo"), []byte("bar")}
	for _, k := range keys {
		vn1, err := r.Lookup(3, k)
		if err != nil {
			t.Fatalf("unexpected err %s", err)
		}
		vn2, err := r2.Lookup(3, k)
		if err != nil {
			t.Fatalf("unexpected err %s", err)
		}
		if len(vn1) != len(vn2) {
			t.Fatalf("result len differs!")
		}
		for idx := range vn1 {
			if vn1[idx].String() != vn2[idx].String() {
				t.Fatalf("results differ!")
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net"
	"net/http"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"sync/atomic"

	"github.com/getlantern/detour"
	"github.com/getlantern/filepersist"
	"github.com/getlantern/pac"

	"github.com/getlantern/flashlight/ui"
)

var (
	isPacOn     = int32(0)
	proxyAddr   string
	pacURL      string
	muPACFile   sync.RWMutex
	pacFile     []byte
	directHosts = make(map[string]bool)
)

func setUpPacTool() error {
	var iconFile string
	if runtime.GOOS == "darwin" {
		// We have to use a short filepath here because Cocoa won't display the
		// icon if the path is too long.
		iconFile := filepath.Join("/tmp", "escalatelantern.ico")
		icon, err := Asset("icons/32on.ico")
		if err != nil {
			return fmt.Errorf("Unable to load escalation prompt icon: %v", err)
		} else {
			err := filepersist.Save(iconFile, icon, 0644)
			if err != nil {
				return fmt.Errorf("Unable to persist icon to disk: %v", err)
			} else {
				log.Debugf("Saved icon file to: %v", iconFile)
			}
		}
	}
	err := pac.EnsureHelperToolPresent("pac-cmd", "Lantern would like to be your system proxy", iconFile)
	if err != nil {
		return fmt.Errorf("Unable to set up pac setting tool: %v", err)
	}
	return nil
}

func setProxyAddr(addr string) {
	proxyAddr = addr
}

func genPACFile() {
	var hosts []string
	for k, v := range directHosts {
		if v {
			hosts = append(hosts, k)
		}
	}
	hostsString := "['" + strings.Join(hosts, "', '") + "']"
	formatter :=
		`var bypassDomains = %s;
		function FindProxyForURL(url, host) {
			if (host == "localhost" || host == "127.0.0.1") {
				return "DIRECT";
			}
			for (var d in bypassDomains) {
				if (host == bypassDomains[d]) {
					return "DIRECT";
				}
			}
			return "PROXY %s; DIRECT";
		}`
	muPACFile.Lock()
	pacFile = []byte(fmt.Sprintf(formatter, hostsString, proxyAddr))
	muPACFile.Unlock()
}

func watchDirectAddrs() {
	detour.DirectAddrCh = make(chan string)
	go func() {
		for {
			addr := <-detour.DirectAddrCh
			if atomic.LoadInt32(&isPacOn) == 0 {
				return
			}
			host, _, err := net.SplitHostPort(addr)
			if err != nil {
				panic("feed watchDirectAddrs with malformated host:port pair")
			}
			directHosts[host] = true
			genPACFile()
			// reapply so browser will fetch the PAC URL again
			doPACOn()
		}
	}()
}

func pacOn() {
	log.Debug("Setting lantern as system proxy")
	handler := func(resp http.ResponseWriter, req *http.Request) {
		resp.Header().Set("Content-Type", "application/x-ns-proxy-autoconfig")
		resp.WriteHeader(http.StatusOK)
		muPACFile.RLock()
		resp.Write(pacFile)
		muPACFile.RUnlock()
	}
	genPACFile()
	pacURL = ui.Handle("/proxy_on.pac", http.HandlerFunc(handler))
	log.Debugf("Serving PAC file at %v", pacURL)
	doPACOn()
	atomic.StoreInt32(&isPacOn, 1)
}

func doPACOn() {
	err := pac.On(pacURL)
	if err != nil {
		log.Errorf("Unable to set lantern as system proxy: %v", err)
		return
	}
}

func pacOff() {
	if atomic.CompareAndSwapInt32(&isPacOn, 1, 0) {
		log.Debug("Unsetting lantern as system proxy")
		err := pac.Off()
		if err != nil {
			log.Errorf("Unable to unset lantern as system proxy: %v", err)
		}
		log.Debug("Unset lantern as system proxy")
	}
}
<commit_msg>turn off and on to let PAC file take effect<commit_after>package main

import (
	"fmt"
	"net"
	"net/http"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"sync/atomic"

	"github.com/getlantern/detour"
	"github.com/getlantern/filepersist"
	"github.com/getlantern/pac"

	"github.com/getlantern/flashlight/ui"
)

var (
	isPacOn     = int32(0)
	proxyAddr   string
	pacURL      string
	muPACFile   sync.RWMutex
	pacFile     []byte
	directHosts = make(map[string]bool)
)

func setUpPacTool() error {
	var iconFile string
	if runtime.GOOS == "darwin" {
		// We have to use a short filepath here because Cocoa won't display the
		// icon if the path is too long.
		iconFile := filepath.Join("/tmp", "escalatelantern.ico")
		icon, err := Asset("icons/32on.ico")
		if err != nil {
			return fmt.Errorf("Unable to load escalation prompt icon: %v", err)
		} else {
			err := filepersist.Save(iconFile, icon, 0644)
			if err != nil {
				return fmt.Errorf("Unable to persist icon to disk: %v", err)
			} else {
				log.Debugf("Saved icon file to: %v", iconFile)
			}
		}
	}
	err := pac.EnsureHelperToolPresent("pac-cmd", "Lantern would like to be your system proxy", iconFile)
	if err != nil {
		return fmt.Errorf("Unable to set up pac setting tool: %v", err)
	}
	return nil
}

func setProxyAddr(addr string) {
	proxyAddr = addr
}

func genPACFile() {
	var hosts []string
	for k, v := range directHosts {
		if v {
			hosts = append(hosts, k)
		}
	}
	hostsString := "['" + strings.Join(hosts, "', '") + "']"
	formatter :=
		`var bypassDomains = %s;
		function FindProxyForURL(url, host) {
			if (host == "localhost" || host == "127.0.0.1") {
				return "DIRECT";
			}
			for (var d in bypassDomains) {
				if (host == bypassDomains[d]) {
					return "DIRECT";
				}
			}
			return "PROXY %s; DIRECT";
		}`
	muPACFile.Lock()
	pacFile = []byte(fmt.Sprintf(formatter, hostsString, proxyAddr))
	muPACFile.Unlock()
}

// watchDirectAddrs adds any site that has accessed directly without error to PAC file
func watchDirectAddrs() {
	detour.DirectAddrCh = make(chan string)
	go func() {
		for {
			addr := <-detour.DirectAddrCh
			if atomic.LoadInt32(&isPacOn) == 0 {
				return
			}
			host, _, err := net.SplitHostPort(addr)
			if err != nil {
				panic("feed watchDirectAddrs with malformated host:port pair")
			}
			directHosts[host] = true
			genPACFile()
			// reapply so browser will fetch the PAC URL again
			doPACOff()
			doPACOn()
		}
	}()
}

func pacOn() {
	log.Debug("Setting lantern as system proxy")
	handler := func(resp http.ResponseWriter, req *http.Request) {
		resp.Header().Set("Content-Type", "application/x-ns-proxy-autoconfig")
		resp.WriteHeader(http.StatusOK)
		muPACFile.RLock()
		resp.Write(pacFile)
		muPACFile.RUnlock()
	}
	genPACFile()
	pacURL = ui.Handle("/proxy_on.pac", http.HandlerFunc(handler))
	log.Debugf("Serving PAC file at %v", pacURL)
	doPACOn()
	atomic.StoreInt32(&isPacOn, 1)
}

func pacOff() {
	if atomic.CompareAndSwapInt32(&isPacOn, 1, 0) {
		log.Debug("Unsetting lantern as system proxy")
		doPACOff()
		log.Debug("Unset lantern as system proxy")
	}
}

func doPACOn() {
	err := pac.On(pacURL)
	if err != nil {
		log.Errorf("Unable to set lantern as system proxy: %v", err)
	}
}

func doPACOff() {
	err := pac.Off()
	if err != nil {
		log.Errorf("Unable to unset lantern as system proxy: %v", err)
	}
}
<|endoftext|>