<commit_before>package dnsimple

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

// GrantType is a string that identifies a particular grant type in the exchange request.
type GrantType string

const (
	// AuthorizationCodeGrant is the type of access token request
	// for an Authorization Code Grant flow.
	// https://tools.ietf.org/html/rfc6749#section-4.1
	AuthorizationCodeGrant = GrantType("authorization_code")
)

// OauthService handles communication with the authorization related
// methods of the DNSimple API.
//
// See https://developer.dnsimple.com/v2/oauth/
type OauthService struct {
	client *Client
}

// AccessToken represents a DNSimple Oauth access token.
type AccessToken struct {
	Token     string `json:"access_token"`
	Type      string `json:"token_type"`
	AccountID int    `json:"account_id"`
}

// ExchangeAuthorizationRequest represents a request to exchange
// an authorization code for an access token.
// RedirectURI is optional, all the other fields are mandatory.
type ExchangeAuthorizationRequest struct {
	Code         string    `json:"code"`
	ClientID     string    `json:"client_id"`
	ClientSecret string    `json:"client_secret"`
	RedirectURI  string    `json:"redirect_uri,omitempty"`
	State        string    `json:"state,omitempty"`
	GrantType    GrantType `json:"grant_type,omitempty"`
}

// ExchangeAuthorizationError represents a failed request to exchange
// an authorization code for an access token.
type ExchangeAuthorizationError struct {
	// HTTP response
	HTTPResponse *http.Response

	ErrorCode        string `json:"error"`
	ErrorDescription string `json:"error_description"`
}

// Error implements the error interface.
func (r *ExchangeAuthorizationError) Error() string {
	return fmt.Sprintf("%v %v: %v %v",
		r.HTTPResponse.Request.Method, r.HTTPResponse.Request.URL,
		r.ErrorCode, r.ErrorDescription)
}

// ExchangeAuthorizationForToken exchanges the short-lived authorization code for an access token
// you can use to authenticate your API calls.
func (s *OauthService) ExchangeAuthorizationForToken(authorization *ExchangeAuthorizationRequest) (*AccessToken, error) {
	path := versioned("/oauth/access_token")

	req, err := s.client.newRequest("POST", path, authorization)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		errorResponse := &ExchangeAuthorizationError{}
		errorResponse.HTTPResponse = resp
		json.NewDecoder(resp.Body).Decode(errorResponse)
		return nil, errorResponse
	}

	accessToken := &AccessToken{}
	err = json.NewDecoder(resp.Body).Decode(accessToken)

	return accessToken, err
}

// AuthorizationOptions represents the option you can use to generate an authorization URL.
type AuthorizationOptions struct {
	RedirectURI string `url:"redirect_uri,omitempty"`
	// A randomly generated string to verify the validity of the request.
	// Currently "state" is required by the DNSimple OAuth implementation, so you must specify it.
	State string `url:"state,omitempty"`
}

// AuthorizeURL generates the URL to authorize an user for an application via the OAuth2 flow.
func (s *OauthService) AuthorizeURL(clientID string, options *AuthorizationOptions) string {
	uri, _ := url.Parse(strings.Replace(s.client.BaseURL, "api.", "", 1))
	uri.Path = "/oauth/authorize"
	query := uri.Query()
	query.Add("client_id", clientID)
	query.Add("response_type", "code")
	uri.RawQuery = query.Encode()

	path, _ := addURLQueryOptions(uri.String(), options)
	return path
}
<commit_msg>Check for encoding error<commit_after>package dnsimple

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

// GrantType is a string that identifies a particular grant type in the exchange request.
type GrantType string

const (
	// AuthorizationCodeGrant is the type of access token request
	// for an Authorization Code Grant flow.
	// https://tools.ietf.org/html/rfc6749#section-4.1
	AuthorizationCodeGrant = GrantType("authorization_code")
)

// OauthService handles communication with the authorization related
// methods of the DNSimple API.
//
// See https://developer.dnsimple.com/v2/oauth/
type OauthService struct {
	client *Client
}

// AccessToken represents a DNSimple Oauth access token.
type AccessToken struct {
	Token     string `json:"access_token"`
	Type      string `json:"token_type"`
	AccountID int    `json:"account_id"`
}

// ExchangeAuthorizationRequest represents a request to exchange
// an authorization code for an access token.
// RedirectURI is optional, all the other fields are mandatory.
type ExchangeAuthorizationRequest struct {
	Code         string    `json:"code"`
	ClientID     string    `json:"client_id"`
	ClientSecret string    `json:"client_secret"`
	RedirectURI  string    `json:"redirect_uri,omitempty"`
	State        string    `json:"state,omitempty"`
	GrantType    GrantType `json:"grant_type,omitempty"`
}

// ExchangeAuthorizationError represents a failed request to exchange
// an authorization code for an access token.
type ExchangeAuthorizationError struct {
	// HTTP response
	HTTPResponse *http.Response

	ErrorCode        string `json:"error"`
	ErrorDescription string `json:"error_description"`
}

// Error implements the error interface.
func (r *ExchangeAuthorizationError) Error() string {
	return fmt.Sprintf("%v %v: %v %v",
		r.HTTPResponse.Request.Method, r.HTTPResponse.Request.URL,
		r.ErrorCode, r.ErrorDescription)
}

// ExchangeAuthorizationForToken exchanges the short-lived authorization code for an access token
// you can use to authenticate your API calls.
func (s *OauthService) ExchangeAuthorizationForToken(authorization *ExchangeAuthorizationRequest) (*AccessToken, error) {
	path := versioned("/oauth/access_token")

	req, err := s.client.newRequest("POST", path, authorization)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		errorResponse := &ExchangeAuthorizationError{}
		err = json.NewDecoder(resp.Body).Decode(errorResponse)
		if err != nil {
			return nil, err
		}
		errorResponse.HTTPResponse = resp
		return nil, errorResponse
	}

	accessToken := &AccessToken{}
	err = json.NewDecoder(resp.Body).Decode(accessToken)

	return accessToken, err
}

// AuthorizationOptions represents the option you can use to generate an authorization URL.
type AuthorizationOptions struct {
	RedirectURI string `url:"redirect_uri,omitempty"`
	// A randomly generated string to verify the validity of the request.
	// Currently "state" is required by the DNSimple OAuth implementation, so you must specify it.
	State string `url:"state,omitempty"`
}

// AuthorizeURL generates the URL to authorize an user for an application via the OAuth2 flow.
func (s *OauthService) AuthorizeURL(clientID string, options *AuthorizationOptions) string {
	uri, _ := url.Parse(strings.Replace(s.client.BaseURL, "api.", "", 1))
	uri.Path = "/oauth/authorize"
	query := uri.Query()
	query.Add("client_id", clientID)
	query.Add("response_type", "code")
	uri.RawQuery = query.Encode()

	path, _ := addURLQueryOptions(uri.String(), options)
	return path
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/miekg/dns"
	"testing"
	"time"
)

func TestDNSResponse(t *testing.T) {
	const TEST_ADDR = "127.0.0.1:9953"

	config := NewConfig()
	config.dnsAddr = TEST_ADDR

	server := NewDNSServer(config)
	go server.Start()

	// Allow some time for server to start
	time.Sleep(250 * time.Millisecond)

	m := new(dns.Msg)
	m.Id = dns.Id()
	m.RecursionDesired = true
	m.Question = []dns.Question{
		dns.Question{"google.com.", dns.TypeA, dns.ClassINET},
	}
	c := new(dns.Client)
	in, _, err := c.Exchange(m, TEST_ADDR)

	if err != nil {
		t.Error("Error response from the server", err)
	}

	if len(in.Answer) < 3 {
		t.Error("DNS request only responded ", len(in.Answer), "answers")
	}

	// // This test is slow and pointless
	// server.Stop()
	//
	// c = new(dns.Client)
	// _, _, err = c.Exchange(m, TEST_ADDR)
	//
	// if err == nil {
	// 	t.Error("Server still running but should be shut down.")
	// }
}

func TestServiceManagement(t *testing.T) {
	list := ServiceListProvider(NewDNSServer(NewConfig()))

	if len(list.GetAllServices()) != 0 {
		t.Error("Initial service count should be 0.")
	}

	A := Service{Name: "bar"}
	list.AddService("foo", A)

	if len(list.GetAllServices()) != 1 {
		t.Error("Service count should be 1.")
	}

	A.Name = "baz"

	s1, err := list.GetService("foo")
	if err != nil {
		t.Error("GetService error", err)
	}

	if s1.Name != "bar" {
		t.Error("Expected: bar got:", s1.Name)
	}

	_, err = list.GetService("boo")

	if err == nil {
		t.Error("Request to boo should have failed")
	}

	list.AddService("boo", Service{Name: "boo"})

	all := list.GetAllServices()

	delete(all, "foo")
	s2 := all["boo"]
	s2.Name = "zoo"

	if len(list.GetAllServices()) != 2 {
		t.Error("Local map change should not remove items")
	}

	if s1, _ = list.GetService("boo"); s1.Name != "boo" {
		t.Error("Local map change should not change items")
	}

	err = list.RemoveService("bar")
	if err == nil {
		t.Error("Removing bar should fail")
	}

	err = list.RemoveService("foo")
	if err != nil {
		t.Error("Removing foo failed", err)
	}

	if len(list.GetAllServices()) != 1 {
		t.Error("Item count after remove should be 1")
	}

}

func TestDNSRequestMatch(t *testing.T) {
	server := NewDNSServer(NewConfig())

	server.AddService("foo", Service{Name: "foo", Image: "bar"})
	server.AddService("baz", Service{Name: "baz", Image: "bar"})
	server.AddService("abc", Service{Name: "def", Image: "ghi"})

	inputs := []struct {
		query, domain string
		expected      int
	}{
		{"docker", "docker", 3},
		{"baz.docker", "docker.local", 0},
		{"docker.local", "docker.local", 3},
		{"foo.docker.local", "docker.local", 0},
		{"bar.docker.local", "docker.local", 2},
		{"foo.bar.docker.local", "docker.local", 1},
		{"*.local", "docker.local", 3},
		{"*.docker.local", "docker.local", 3},
		{"bar.*.local", "docker.local", 2},
		{"*.*.local", "docker.local", 3},
		{"foo.*.local", "docker.local", 0},
		{"bar.*.docker.local", "docker.local", 0},
		{"foo.*.docker", "docker", 1},
		{"baz.foo.bar.docker.local", "docker.local", 1},
		{"foo.bar", "baz.foo.bar", 3},
	}

	for _, input := range inputs {
		server.config.domain = NewDomain(input.domain)

		t.Log(input.query, input.domain)

		actual := 0
		for _ = range server.queryServices(input.query) {
			actual++
		}

		if actual != input.expected {
			t.Error(input, "Expected:", input.expected, "Got:", actual)
		}
	}
}
<commit_msg>Add DNS request tests<commit_after>package main

import (
	"github.com/miekg/dns"
	"net"
	"testing"
	"time"
)

func TestDNSResponse(t *testing.T) {
	const TEST_ADDR = "127.0.0.1:9953"

	config := NewConfig()
	config.dnsAddr = TEST_ADDR

	server := NewDNSServer(config)
	go server.Start()

	// Allow some time for server to start
	time.Sleep(250 * time.Millisecond)

	m := new(dns.Msg)
	m.Id = dns.Id()
	m.RecursionDesired = true
	m.Question = []dns.Question{
		dns.Question{"google.com.", dns.TypeA, dns.ClassINET},
	}
	c := new(dns.Client)
	in, _, err := c.Exchange(m, TEST_ADDR)

	if err != nil {
		t.Error("Error response from the server", err)
	}

	if len(in.Answer) < 3 {
		t.Error("DNS request only responded ", len(in.Answer), "answers")
	}

	server.AddService("foo", Service{Name: "foo", Image: "bar", Ip: net.ParseIP("127.0.0.1")})
	server.AddService("baz", Service{Name: "baz", Image: "bar", Ip: net.ParseIP("127.0.0.1")})

	var inputs = []struct {
		query    string
		expected int
	}{
		{"docker.", 2},
		{"*.docker.", 2},
		{"bar.docker.", 2},
		{"foo.docker.", 0},
		{"baz.bar.docker.", 1},
	}

	for _, input := range inputs {
		t.Log(input.query)
		m := new(dns.Msg)
		m.Id = dns.Id()
		m.RecursionDesired = true
		m.Question = []dns.Question{
			dns.Question{input.query, dns.TypeA, dns.ClassINET},
		}
		c := new(dns.Client)
		in, _, err := c.Exchange(m, TEST_ADDR)
		if err != nil {
			t.Error("Error response from the server", err)
			break
		}

		if len(in.Answer) != input.expected {
			t.Error(input, "Expected:", input.expected, " Got:", len(in.Answer))
		}
	}

	// // This test is slow and pointless
	// server.Stop()
	//
	// c = new(dns.Client)
	// _, _, err = c.Exchange(m, TEST_ADDR)
	//
	// if err == nil {
	// 	t.Error("Server still running but should be shut down.")
	// }
}

func TestServiceManagement(t *testing.T) {
	list := ServiceListProvider(NewDNSServer(NewConfig()))

	if len(list.GetAllServices()) != 0 {
		t.Error("Initial service count should be 0.")
	}

	A := Service{Name: "bar"}
	list.AddService("foo", A)

	if len(list.GetAllServices()) != 1 {
		t.Error("Service count should be 1.")
	}

	A.Name = "baz"

	s1, err := list.GetService("foo")
	if err != nil {
		t.Error("GetService error", err)
	}

	if s1.Name != "bar" {
		t.Error("Expected: bar got:", s1.Name)
	}

	_, err = list.GetService("boo")

	if err == nil {
		t.Error("Request to boo should have failed")
	}

	list.AddService("boo", Service{Name: "boo"})

	all := list.GetAllServices()

	delete(all, "foo")
	s2 := all["boo"]
	s2.Name = "zoo"

	if len(list.GetAllServices()) != 2 {
		t.Error("Local map change should not remove items")
	}

	if s1, _ = list.GetService("boo"); s1.Name != "boo" {
		t.Error("Local map change should not change items")
	}

	err = list.RemoveService("bar")
	if err == nil {
		t.Error("Removing bar should fail")
	}

	err = list.RemoveService("foo")
	if err != nil {
		t.Error("Removing foo failed", err)
	}

	if len(list.GetAllServices()) != 1 {
		t.Error("Item count after remove should be 1")
	}

}

func TestDNSRequestMatch(t *testing.T) {
	server := NewDNSServer(NewConfig())

	server.AddService("foo", Service{Name: "foo", Image: "bar"})
	server.AddService("baz", Service{Name: "baz", Image: "bar"})
	server.AddService("abc", Service{Name: "def", Image: "ghi"})

	inputs := []struct {
		query, domain string
		expected      int
	}{
		{"docker", "docker", 3},
		{"baz.docker", "docker.local", 0},
		{"docker.local", "docker.local", 3},
		{"foo.docker.local", "docker.local", 0},
		{"bar.docker.local", "docker.local", 2},
		{"foo.bar.docker.local", "docker.local", 1},
		{"*.local", "docker.local", 3},
		{"*.docker.local", "docker.local", 3},
		{"bar.*.local", "docker.local", 2},
		{"*.*.local", "docker.local", 3},
		{"foo.*.local", "docker.local", 0},
		{"bar.*.docker.local", "docker.local", 0},
		{"foo.*.docker", "docker", 1},
		{"baz.foo.bar.docker.local", "docker.local", 1},
		{"foo.bar", "baz.foo.bar", 3},
	}

	for _, input := range inputs {
		server.config.domain = NewDomain(input.domain)

		t.Log(input.query, input.domain)

		actual := 0
		for _ = range server.queryServices(input.query) {
			actual++
		}

		if actual != input.expected {
			t.Error(input, "Expected:", input.expected, "Got:", actual)
		}
	}
}
<|endoftext|>


<commit_before>package main

import "strings"
import "strconv"
import "fmt"
import "errors"
import "net/http"
import "time"
import "html"
import "log"
import "io"
import "bufio"
import "bytes"
import "encoding/xml"
import "golang.org/x/tools/blog/atom"

// TODO that shouldn't be a constant. Parse as argument?
// Maximum size a request for a bug-xml is read in byte.
var maxBugRequestRead int64 = 1 * 1024 * 1024 // 1MiB per default

// TODO that shouldn't be a constant. Parse as argument?
// Maximum number of requests per second. Set to something negative to disable
var maxRequestsPerSecond int = 5

const bugzillaDateFormat = "2006-01-02 15:04:05 -0700"

// Channel to block on during too many requests in a second
var tooManyRequestsBlocker chan bool = make(chan bool)

// returns the minimum of the given values
func min(a int, b int) int {
    if a <= b {
        return a
    } else {
        return b
    }
}

// Read from r until given string is found. Appends toAppend afterwards if string
// is found and in any case returns the result
func readUntilString(r io.Reader, until string, toAppend string) (string, error) {
    var buffer bytes.Buffer
    eofReached := false
    rs := bufio.NewReader(io.LimitReader(r, maxBugRequestRead))

    for !eofReached {
        str, err := rs.ReadString('\n')

        if err == io.EOF {
            eofReached = true
        } else if err != nil {
            log.Printf("Error during reading from url: %s\n", err)
            return "", err
        }

        index := strings.Index(str, until)

        if index == -1 {
            buffer.WriteString(str)
        } else {
            buffer.WriteString(str[:index])
            buffer.WriteString(toAppend)
            break
        }
    }

    return buffer.String(), nil
}

// Requests the bug from given url
func doRequest(target string) (string, error) {
    resp, err := http.Get(target)

    if err != nil {
        log.Printf("Error during GET to url \"%s\": %s\n", target, err)
        return "", err
    }

    defer resp.Body.Close()

    // TODO: maybe we should search for something more clever to abort. <attachment could be given by a user in a report
    return readUntilString(resp.Body, "<attachment", "</bug></bugzilla>")
}

// converts the given xml string into an atom feed
func convertXmlToAtom(inXml string) (string, error) {
    type Who struct {
        Name string `xml:",chardata"`
        RealName string `xml:"name,attr"`
    }

    getFormatedName := func(w Who) string {
        if w.RealName == "" {
            return w.Name
        } else {
            return w.RealName + " (" + w.Name + ")"
        }
    }

    type Comment struct {
        CommentId int `xml:"commentid"`
        CommentCount int `xml:"comment_count"`
        AttachmentID int `xml:"attachid"`
        Who Who `xml:"who"`
        When string `xml:"bug_when"`
        Text string `xml:"thetext"`
        // TODO: add attachments?
    }

    type InResult struct {
        Urlbase string `xml:"urlbase,attr"`
        BugId int `xml:"bug>bug_id"`
        Description string `xml:"bug>short_desc"`
        Comments []Comment `xml:"bug>long_desc"`
    }

    inResult := InResult{}
    err := xml.Unmarshal([]byte(inXml), &inResult)
    if err != nil {
        log.Printf("Error during unmarshalling the xml: %s\n", err)
        return "", err
    } else if len(inResult.Comments) == 0 {
        // One comment, the initial one, should always be available
        err := errors.New("Zero comments in bug. There should be at least the initial one.")
        log.Printf("Error after unmarshalling the xml: %s\n", err)
        return "", err
    }

    updateTime, err := time.Parse(bugzillaDateFormat, inResult.Comments[len(inResult.Comments)-1].When)
    if err != nil {
        log.Printf("Couldn't parse updateTime in initial comment: %s\n", err)
        return "", err
    }

    inUrl := fmt.Sprintf("%s/show_bug.cgi?id=%d", inResult.Urlbase, inResult.BugId)
    attachmentUrl := fmt.Sprintf("%s/attachment.cgi?id=", inResult.Urlbase)

    feed := &atom.Feed{
        Title: inResult.Description,
        ID: inUrl,
        Link: []atom.Link{atom.Link{Href: inUrl, Rel: "alternate"}},
        Updated: atom.Time(updateTime),
        Author: &atom.Person{Name: getFormatedName(inResult.Comments[0].Who)},
        Entry: make([]*atom.Entry, 0, len(inResult.Comments)),
    }

    for i, comment := range inResult.Comments {
        creationTime, err := time.Parse(bugzillaDateFormat, comment.When)
        if err != nil {
            log.Printf("Couldn't parse updateTime in comment %d: %s\n", i, err)
            return "", err
        }

        links := []atom.Link{atom.Link{Href: inUrl + "#c" + strconv.Itoa(comment.CommentCount), Rel: "alternate"}}
        if comment.AttachmentID != 0 {
            links = append(links, atom.Link{Href: attachmentUrl + strconv.Itoa(comment.AttachmentID), Rel: "enclosure"})
        }

        entry := &atom.Entry{
            Title: getFormatedName(comment.Who) + ": " + comment.Text[:min(100, len(comment.Text))],
            ID: inUrl + "#c" + strconv.Itoa(comment.CommentCount),
            Link: links,
            Published: atom.Time(creationTime),
            Author: &atom.Person{Name: getFormatedName(comment.Who)},
            Content: &atom.Text{Type: "html", Body: strings.Replace(html.EscapeString(comment.Text), "\n", "
", -1)},
        }

        feed.Entry = append(feed.Entry, entry)
    }

    atom, err := xml.MarshalIndent(feed, "", "\t")
    if err != nil {
        log.Printf("Error during creating the atom feed: %s\n", err)
        return "", err
    }

    return xml.Header + string(atom), nil
}

func handleConvert(w http.ResponseWriter, r *http.Request) {
    // TODO: do some security: What about local domains, etc... Is there even an url? Test for this stuff!
    // TODO: Do not always add ctype=xml, do some security checking or so.. Add via function? Also it's broken when only an domain is entered, or domain+port without / at the end
    // TODO: remove anchors as #c0

    // Block during too many requests in the last second
    if maxRequestsPerSecond >= 0 {
        <-tooManyRequestsBlocker
    }

    target := r.FormValue("url") + "&ctype=xml"

    // if the user didn't give a protocol simply assume http
    if !(strings.HasPrefix(target, "http://") || strings.HasPrefix(target, "https://")) {
        target = "http://" + target
    }

    inXml, err := doRequest(target)
    if err != nil {
        errStr := fmt.Sprintf("Error occurred during fetching the url \"%s\": %s\nAre you sure the url is correct?", target, err.Error())
        http.Error(w, errStr, http.StatusInternalServerError)
        return
    }

    atom, err := convertXmlToAtom(inXml)
    if err != nil {
        errStr := fmt.Sprintf("Error occurred during conversion of the url \"%s\" to atom: %s\nAre you sure the url is correct?", target, err.Error())
        http.Error(w, errStr, http.StatusInternalServerError)
        return
    }

    fmt.Fprintf(w, "%s", atom)
}

func handleMain(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s", `

<title>bugzillatoatom</title>

<form action=convert>
    Convert a Bugzilla bug entry into an Atom feed. Enter an url:
    <input type="text" name="url">

`)
    // TODO: do some pretty gui stuff
}

func main() {
    // Add a timeout for the default http.Get() in case something goes wrong
    // on the oher side.
    http.DefaultClient = &http.Client{Timeout: time.Second * 30}

    for i := 0; i < maxRequestsPerSecond; i++ {
        go func() {
            for {
                tooManyRequestsBlocker <- true
                time.Sleep(time.Second)
            }
        }()
    }

    http.HandleFunc("/convert", handleConvert)
    http.HandleFunc("/", handleMain)

    http.ListenAndServe(":9080", nil)
}<commit_msg>use net/url for url-parsing<commit_after>package main

import "strings"
import "strconv"
import "fmt"
import "errors"
import "net/http"
import "net/url"
import "time"
import "html"
import "log"
import "io"
import "bufio"
import "bytes"
import "encoding/xml"
import "golang.org/x/tools/blog/atom"

// TODO that shouldn't be a constant. Parse as argument?
// Maximum size a request for a bug-xml is read in byte.
var maxBugRequestRead int64 = 1 * 1024 * 1024 // 1MiB per default

// TODO that shouldn't be a constant. Parse as argument?
// Maximum number of requests per second. Set to something negative to disable
var maxRequestsPerSecond int = 5

const bugzillaDateFormat = "2006-01-02 15:04:05 -0700"

// Channel to block on during too many requests in a second
var tooManyRequestsBlocker chan bool = make(chan bool)

// returns the minimum of the given values
func min(a int, b int) int {
    if a <= b {
        return a
    } else {
        return b
    }
}

// Read from r until given string is found. Appends toAppend afterwards if string
// is found and in any case returns the result
func readUntilString(r io.Reader, until string, toAppend string) (string, error) {
    var buffer bytes.Buffer
    eofReached := false
    rs := bufio.NewReader(io.LimitReader(r, maxBugRequestRead))

    for !eofReached {
        str, err := rs.ReadString('\n')

        if err == io.EOF {
            eofReached = true
        } else if err != nil {
            log.Printf("Error during reading from url: %s\n", err)
            return "", err
        }

        index := strings.Index(str, until)

        if index == -1 {
            buffer.WriteString(str)
        } else {
            buffer.WriteString(str[:index])
            buffer.WriteString(toAppend)
            break
        }
    }

    return buffer.String(), nil
}

// Requests the bug from given url
func doRequest(target string) (string, error) {
    resp, err := http.Get(target)

    if err != nil {
        log.Printf("Error during GET to url \"%s\": %s\n", target, err)
        return "", err
    }

    defer resp.Body.Close()

    // TODO: maybe we should search for something more clever to abort. <attachment could be given by a user in a report
    return readUntilString(resp.Body, "<attachment", "</bug></bugzilla>")
}

// converts the given xml string into an atom feed
func convertXmlToAtom(inXml string) (string, error) {
    type Who struct {
        Name string `xml:",chardata"`
        RealName string `xml:"name,attr"`
    }

    getFormatedName := func(w Who) string {
        if w.RealName == "" {
            return w.Name
        } else {
            return w.RealName + " (" + w.Name + ")"
        }
    }

    type Comment struct {
        CommentId int `xml:"commentid"`
        CommentCount int `xml:"comment_count"`
        AttachmentID int `xml:"attachid"`
        Who Who `xml:"who"`
        When string `xml:"bug_when"`
        Text string `xml:"thetext"`
        // TODO: add attachments?
    }

    type InResult struct {
        Urlbase string `xml:"urlbase,attr"`
        BugId int `xml:"bug>bug_id"`
        Description string `xml:"bug>short_desc"`
        Comments []Comment `xml:"bug>long_desc"`
    }

    inResult := InResult{}
    err := xml.Unmarshal([]byte(inXml), &inResult)
    if err != nil {
        log.Printf("Error during unmarshalling the xml: %s\n", err)
        return "", err
    } else if len(inResult.Comments) == 0 {
        // One comment, the initial one, should always be available
        err := errors.New("Zero comments in bug. There should be at least the initial one.")
        log.Printf("Error after unmarshalling the xml: %s\n", err)
        return "", err
    }

    updateTime, err := time.Parse(bugzillaDateFormat, inResult.Comments[len(inResult.Comments)-1].When)
    if err != nil {
        log.Printf("Couldn't parse updateTime in initial comment: %s\n", err)
        return "", err
    }

    inUrl := fmt.Sprintf("%s/show_bug.cgi?id=%d", inResult.Urlbase, inResult.BugId)
    attachmentUrl := fmt.Sprintf("%s/attachment.cgi?id=", inResult.Urlbase)

    feed := &atom.Feed{
        Title: inResult.Description,
        ID: inUrl,
        Link: []atom.Link{atom.Link{Href: inUrl, Rel: "alternate"}},
        Updated: atom.Time(updateTime),
        Author: &atom.Person{Name: getFormatedName(inResult.Comments[0].Who)},
        Entry: make([]*atom.Entry, 0, len(inResult.Comments)),
    }

    for i, comment := range inResult.Comments {
        creationTime, err := time.Parse(bugzillaDateFormat, comment.When)
        if err != nil {
            log.Printf("Couldn't parse updateTime in comment %d: %s\n", i, err)
            return "", err
        }

        links := []atom.Link{atom.Link{Href: inUrl + "#c" + strconv.Itoa(comment.CommentCount), Rel: "alternate"}}
        if comment.AttachmentID != 0 {
            links = append(links, atom.Link{Href: attachmentUrl + strconv.Itoa(comment.AttachmentID), Rel: "enclosure"})
        }

        entry := &atom.Entry{
            Title: getFormatedName(comment.Who) + ": " + comment.Text[:min(100, len(comment.Text))],
            ID: inUrl + "#c" + strconv.Itoa(comment.CommentCount),
            Link: links,
            Published: atom.Time(creationTime),
            Author: &atom.Person{Name: getFormatedName(comment.Who)},
            Content: &atom.Text{Type: "html", Body: strings.Replace(html.EscapeString(comment.Text), "\n", "
", -1)},
        }

        feed.Entry = append(feed.Entry, entry)
    }

    atom, err := xml.MarshalIndent(feed, "", "\t")
    if err != nil {
        log.Printf("Error during creating the atom feed: %s\n", err)
        return "", err
    }

    return xml.Header + string(atom), nil
}

func handleConvert(w http.ResponseWriter, r *http.Request) {
    // TODO: do some security: What about local domains, etc... Test for this stuff!

    // Block during too many requests in the last second
    if maxRequestsPerSecond >= 0 {
        <-tooManyRequestsBlocker
    }

    formValueUrl := r.FormValue("url")

    // if the user didn't give a protocol simply assume http
    if !(strings.HasPrefix(formValueUrl, "http://") || strings.HasPrefix(formValueUrl, "https://")) {
        formValueUrl = "http://" + formValueUrl
    }

    target, err := url.Parse(formValueUrl)

    if err != nil {
        errStr := fmt.Sprintf("Error occurred during parsing the url \"%s\": %s\nAre you sure the url is correct?", r.FormValue("url"), err.Error())
        http.Error(w, errStr, http.StatusInternalServerError)
        return
    }

    parsedQuery := target.Query()
    parsedQuery.Set("ctype", "xml")
    target.RawQuery = parsedQuery.Encode()
    target.Fragment = ""

    if target.Host == "" {
        errStr := fmt.Sprintf("Error occurred during parsing the url \"%s\": No host recognized.\nAre you sure the url is correct?", formValueUrl)
        http.Error(w, errStr, http.StatusInternalServerError)
        return
    }

    inXml, err := doRequest(target.String())
    if err != nil {
        errStr := fmt.Sprintf("Error occurred during fetching the url \"%s\": %s\nAre you sure the url is correct?", target.String(), err.Error())
        http.Error(w, errStr, http.StatusInternalServerError)
        return
    }

    atom, err := convertXmlToAtom(inXml)
    if err != nil {
        errStr := fmt.Sprintf("Error occurred during conversion of the url \"%s\" to atom: %s\nAre you sure the url is correct?", target.String(), err.Error())
        http.Error(w, errStr, http.StatusInternalServerError)
        return
    }

    fmt.Fprintf(w, "%s", atom)
}

func handleMain(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s", `

<title>bugzillatoatom</title>

<form action=convert>
    Convert a Bugzilla bug entry into an Atom feed. Enter an url:
    <input type="text" name="url">

`)
    // TODO: do some pretty gui stuff
}

func main() {
    // Add a timeout for the default http.Get() in case something goes wrong
    // on the oher side.
    http.DefaultClient = &http.Client{Timeout: time.Second * 30}

    for i := 0; i < maxRequestsPerSecond; i++ {
        go func() {
            for {
                tooManyRequestsBlocker <- true
                time.Sleep(time.Second)
            }
        }()
    }

    http.HandleFunc("/convert", handleConvert)
    http.HandleFunc("/", handleMain)

    http.ListenAndServe(":9080", nil)
}<|endoftext|>


<commit_before>package services

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"time"

	"go.uber.org/zap"

	"github.com/fairway-corp/swagchat-api/datastore"
	"github.com/fairway-corp/swagchat-api/models"
	"github.com/fairway-corp/swagchat-api/notification"
	"github.com/fairway-corp/swagchat-api/utils"
)

func PostRoom(post *models.Room) (*models.Room, *models.ProblemDetail) {
	if pd := post.IsValid(); pd != nil {
		return nil, pd
	}
	post.BeforeSave()

	dRes := datastore.GetProvider().InsertRoom(post)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	return dRes.Data.(*models.Room), nil
}

func GetRooms(values url.Values) (*models.Rooms, *models.ProblemDetail) {
	dRes := datastore.GetProvider().SelectRooms()
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}

	rooms := &models.Rooms{
		Rooms: dRes.Data.([]*models.Room),
	}
	dRes = datastore.GetProvider().SelectCountRooms()
	rooms.AllCount = dRes.Data.(int64)
	return rooms, nil
}

func GetRoom(roomId string) (*models.Room, *models.ProblemDetail) {
	room, pd := selectRoom(roomId)
	if pd != nil {
		return nil, pd
	}

	dRes := datastore.GetProvider().SelectUsersForRoom(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	room.Users = dRes.Data.([]*models.UserForRoom)

	dRes = datastore.GetProvider().SelectCountMessagesByRoomId(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	room.MessageCount = dRes.Data.(int64)
	return room, nil
}

func PutRoom(put *models.Room) (*models.Room, *models.ProblemDetail) {
	room, pd := selectRoom(put.RoomId)
	if pd != nil {
		return nil, pd
	}

	if pd := room.Put(put); pd != nil {
		return nil, pd
	}

	if pd := room.IsValid(); pd != nil {
		return nil, pd
	}
	room.BeforeSave()

	dRes := datastore.GetProvider().UpdateRoom(room)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	return dRes.Data.(*models.Room), nil
}

func DeleteRoom(roomId string) *models.ProblemDetail {
	room, pd := selectRoom(roomId)
	if pd != nil {
		return pd
	}

	if room.NotificationTopicId != "" {
		nRes := <-notification.GetProvider().DeleteTopic(room.NotificationTopicId)
		if nRes.ProblemDetail != nil {
			return nRes.ProblemDetail
		}
	}

	room.NotificationTopicId = ""
	room.Deleted = time.Now().Unix()
	dRes := datastore.GetProvider().UpdateRoomDeleted(roomId)
	if dRes.ProblemDetail != nil {
		return dRes.ProblemDetail
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	go unsubscribeByRoomId(ctx, roomId)

	return nil
}

func GetRoomMessages(roomId string, params url.Values) (*models.Messages, *models.ProblemDetail) {
	var err error
	limit := 10
	offset := 0
	order := "ASC"
	if limitArray, ok := params["limit"]; ok {
		limit, err = strconv.Atoi(limitArray[0])
		if err != nil {
			return nil, &models.ProblemDetail{
				Title:     "Request parameter error. (Get room's message list)",
				Status:    http.StatusBadRequest,
				ErrorName: models.ERROR_NAME_INVALID_PARAM,
				InvalidParams: []models.InvalidParam{
					models.InvalidParam{
						Name:   "limit",
						Reason: "limit is incorrect.",
					},
				},
			}
		}
	}
	if offsetArray, ok := params["offset"]; ok {
		offset, err = strconv.Atoi(offsetArray[0])
		if err != nil {
			return nil, &models.ProblemDetail{
				Title:     "Request parameter error. (Get room's message list)",
				Status:    http.StatusBadRequest,
				ErrorName: models.ERROR_NAME_INVALID_PARAM,
				InvalidParams: []models.InvalidParam{
					models.InvalidParam{
						Name:   "offset",
						Reason: "offset is incorrect.",
					},
				},
			}
		}
	}
	if orderArray, ok := params["order"]; ok {
		order := orderArray[0]
		allowedOrders := []string{
			"DESC",
			"desc",
			"ASC",
			"asc",
		}
		if utils.SearchStringValueInSlice(allowedOrders, order) {
			return nil, &models.ProblemDetail{
				Title:     "Request parameter error. (Get room's message list)",
				Status:    http.StatusBadRequest,
				ErrorName: models.ERROR_NAME_INVALID_PARAM,
				InvalidParams: []models.InvalidParam{
					models.InvalidParam{
						Name:   "order",
						Reason: "order is incorrect.",
					},
				},
			}
		}
	}

	dRes := datastore.GetProvider().SelectMessages(roomId, limit, offset, order)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	messages := &models.Messages{
		Messages: dRes.Data.([]*models.Message),
	}

	dRes = datastore.GetProvider().SelectCountMessagesByRoomId(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	messages.AllCount = dRes.Data.(int64)
	return messages, nil
}

func selectRoom(roomId string) (*models.Room, *models.ProblemDetail) {
	dRes := datastore.GetProvider().SelectRoom(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	if dRes.Data == nil {
		return nil, &models.ProblemDetail{
			Status: http.StatusNotFound,
		}
	}
	return dRes.Data.(*models.Room), nil
}

func unsubscribeByRoomId(ctx context.Context, roomId string) {
	dRes := datastore.GetProvider().SelectSubscriptionsByRoomId(roomId)
	if dRes.ProblemDetail != nil {
		pdBytes, _ := json.Marshal(dRes.ProblemDetail)
		utils.AppLogger.Error("",
			zap.String("problemDetail", string(pdBytes)),
			zap.String("err", fmt.Sprintf("%+v", dRes.ProblemDetail.Error)),
		)
	}
	unsubscribe(ctx, dRes.Data.([]*models.Subscription))
}
<commit_msg>Functionalized request paging params.<commit_after>package services

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strconv"
	"time"

	"github.com/fairway-corp/swagchat-api/datastore"
	"github.com/fairway-corp/swagchat-api/models"
	"github.com/fairway-corp/swagchat-api/notification"
	"github.com/fairway-corp/swagchat-api/utils"
	"go.uber.org/zap"
)

func PostRoom(post *models.Room) (*models.Room, *models.ProblemDetail) {
	if pd := post.IsValid(); pd != nil {
		return nil, pd
	}
	post.BeforeSave()

	dRes := datastore.GetProvider().InsertRoom(post)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	return dRes.Data.(*models.Room), nil
}

func GetRooms(values url.Values) (*models.Rooms, *models.ProblemDetail) {
	dRes := datastore.GetProvider().SelectRooms()
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}

	rooms := &models.Rooms{
		Rooms: dRes.Data.([]*models.Room),
	}
	dRes = datastore.GetProvider().SelectCountRooms()
	rooms.AllCount = dRes.Data.(int64)
	return rooms, nil
}

func GetRoom(roomId string) (*models.Room, *models.ProblemDetail) {
	room, pd := selectRoom(roomId)
	if pd != nil {
		return nil, pd
	}

	dRes := datastore.GetProvider().SelectUsersForRoom(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	room.Users = dRes.Data.([]*models.UserForRoom)

	dRes = datastore.GetProvider().SelectCountMessagesByRoomId(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	room.MessageCount = dRes.Data.(int64)
	return room, nil
}

func PutRoom(put *models.Room) (*models.Room, *models.ProblemDetail) {
	room, pd := selectRoom(put.RoomId)
	if pd != nil {
		return nil, pd
	}

	if pd := room.Put(put); pd != nil {
		return nil, pd
	}

	if pd := room.IsValid(); pd != nil {
		return nil, pd
	}
	room.BeforeSave()

	dRes := datastore.GetProvider().UpdateRoom(room)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	return dRes.Data.(*models.Room), nil
}

func DeleteRoom(roomId string) *models.ProblemDetail {
	room, pd := selectRoom(roomId)
	if pd != nil {
		return pd
	}

	if room.NotificationTopicId != "" {
		nRes := <-notification.GetProvider().DeleteTopic(room.NotificationTopicId)
		if nRes.ProblemDetail != nil {
			return nRes.ProblemDetail
		}
	}

	room.NotificationTopicId = ""
	room.Deleted = time.Now().Unix()
	dRes := datastore.GetProvider().UpdateRoomDeleted(roomId)
	if dRes.ProblemDetail != nil {
		return dRes.ProblemDetail
	}

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	go unsubscribeByRoomId(ctx, roomId)

	return nil
}

func GetRoomMessages(roomId string, params url.Values) (*models.Messages, *models.ProblemDetail) {
	limit, offset, order, pd := setPagingParams(params)
	if pd != nil {
		return nil, pd
	}

	dRes := datastore.GetProvider().SelectMessages(roomId, limit, offset, order)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	messages := &models.Messages{
		Messages: dRes.Data.([]*models.Message),
	}

	dRes = datastore.GetProvider().SelectCountMessagesByRoomId(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	messages.AllCount = dRes.Data.(int64)
	return messages, nil
}

func selectRoom(roomId string) (*models.Room, *models.ProblemDetail) {
	dRes := datastore.GetProvider().SelectRoom(roomId)
	if dRes.ProblemDetail != nil {
		return nil, dRes.ProblemDetail
	}
	if dRes.Data == nil {
		return nil, &models.ProblemDetail{
			Status: http.StatusNotFound,
		}
	}
	return dRes.Data.(*models.Room), nil
}

func unsubscribeByRoomId(ctx context.Context, roomId string) {
	dRes := datastore.GetProvider().SelectSubscriptionsByRoomId(roomId)
	if dRes.ProblemDetail != nil {
		pdBytes, _ := json.Marshal(dRes.ProblemDetail)
		utils.AppLogger.Error("",
			zap.String("problemDetail", string(pdBytes)),
			zap.String("err", fmt.Sprintf("%+v", dRes.ProblemDetail.Error)),
		)
	}
	unsubscribe(ctx, dRes.Data.([]*models.Subscription))
}

func setPagingParams(params url.Values) (int, int, string, *models.ProblemDetail) {
	var err error
	limit := 10
	offset := 0
	order := "ASC"
	if limitArray, ok := params["limit"]; ok {
		limit, err = strconv.Atoi(limitArray[0])
		if err != nil {
			return limit, offset, order, &models.ProblemDetail{
				Title:     "Request parameter error.",
				Status:    http.StatusBadRequest,
				ErrorName: models.ERROR_NAME_INVALID_PARAM,
				InvalidParams: []models.InvalidParam{
					models.InvalidParam{
						Name:   "limit",
						Reason: "limit is incorrect.",
					},
				},
			}
		}
	}
	if offsetArray, ok := params["offset"]; ok {
		offset, err = strconv.Atoi(offsetArray[0])
		if err != nil {
			return limit, offset, order, &models.ProblemDetail{
				Title:     "Request parameter error.",
				Status:    http.StatusBadRequest,
				ErrorName: models.ERROR_NAME_INVALID_PARAM,
				InvalidParams: []models.InvalidParam{
					models.InvalidParam{
						Name:   "offset",
						Reason: "offset is incorrect.",
					},
				},
			}
		}
	}
	if orderArray, ok := params["order"]; ok {
		order := orderArray[0]
		allowedOrders := []string{
			"DESC",
			"desc",
			"ASC",
			"asc",
		}
		if utils.SearchStringValueInSlice(allowedOrders, order) {
			return limit, offset, order, &models.ProblemDetail{
				Title:     "Request parameter error.",
				Status:    http.StatusBadRequest,
				ErrorName: models.ERROR_NAME_INVALID_PARAM,
				InvalidParams: []models.InvalidParam{
					models.InvalidParam{
						Name:   "order",
						Reason: "order is incorrect.",
					},
				},
			}
		}
	}
	return limit, offset, order, nil
}
<|endoftext|>


<commit_before>package listeners

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

	"github.com/getlantern/idletiming"
)

// Wrapped idleConnListener that generates the wrapped idleConn
type idleConnListener struct {
	net.Listener
	idleTimeout time.Duration
}

func NewIdleConnListener(l net.Listener, timeout time.Duration) net.Listener {
	return &idleConnListener{
		Listener:    l,
		idleTimeout: timeout,
	}
}

func (l *idleConnListener) Accept() (c net.Conn, err error) {
	conn, err := l.Listener.Accept()
	if err != nil {
		return nil, err
	}

	iConn := idletiming.Conn(
		conn,
		l.idleTimeout,
		func() {
			conn.Close()
		},
	)

	sac, _ := conn.(WrapConnEmbeddable)
	return &idleConn{
		WrapConnEmbeddable: sac,
		IdleTimingConn:     *iConn,
	}, err
}

// Wrapped IdleTimingConn that supports OnState
type idleConn struct {
	WrapConnEmbeddable
	idletiming.IdleTimingConn
}

func (c *idleConn) OnState(s http.ConnState) {
	if c.WrapConnEmbeddable != nil {
		c.WrapConnEmbeddable.OnState(s)
	}
}

func (c *idleConn) ControlMessage(msgType string, data interface{}) {
	// Simply pass down the control message to the wrapped connection
	if c.WrapConnEmbeddable != nil {
		c.WrapConnEmbeddable.ControlMessage(msgType, data)
	}
}
<commit_msg>Made idleConn embed net.Conn instead of IdleTimingConn<commit_after>package listeners

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

	"github.com/getlantern/idletiming"
)

// Wrapped idleConnListener that generates the wrapped idleConn
type idleConnListener struct {
	net.Listener
	idleTimeout time.Duration
}

func NewIdleConnListener(l net.Listener, timeout time.Duration) net.Listener {
	return &idleConnListener{
		Listener:    l,
		idleTimeout: timeout,
	}
}

func (l *idleConnListener) Accept() (c net.Conn, err error) {
	conn, err := l.Listener.Accept()
	if err != nil {
		return nil, err
	}

	iConn := idletiming.Conn(
		conn,
		l.idleTimeout,
		func() {
			conn.Close()
		},
	)

	sac, _ := conn.(WrapConnEmbeddable)
	return &idleConn{
		WrapConnEmbeddable: sac,
		Conn:               iConn,
	}, err
}

// Wrapped IdleTimingConn that supports OnState
type idleConn struct {
	WrapConnEmbeddable
	net.Conn
}

func (c *idleConn) OnState(s http.ConnState) {
	if c.WrapConnEmbeddable != nil {
		c.WrapConnEmbeddable.OnState(s)
	}
}

func (c *idleConn) ControlMessage(msgType string, data interface{}) {
	// Simply pass down the control message to the wrapped connection
	if c.WrapConnEmbeddable != nil {
		c.WrapConnEmbeddable.ControlMessage(msgType, data)
	}
}
<|endoftext|>


<commit_before>// Copyright 2017 tsuru 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 integration

import (
	"fmt"
	"os"
	"strings"

	check "gopkg.in/check.v1"
)

func (s *S) getInstallerConfig() string {
	hosts := len(provisioners)
	for _, m := range clusterManagers {
		if req, ok := m.(interface {
			RequiredNodes() int
		}); ok {
			hosts += req.RequiredNodes()
		}
	}
	// if no host is set, add one, so Tsuru can build platforms
	if hosts == 0 {
		hosts = 1
	}
	return fmt.Sprintf(`driver:
  name: virtualbox
  options:
    virtualbox-cpu-count: 2
    virtualbox-memory: 2048
docker-flags:
  - experimental
hosts:
  apps:
    size: %d
components:
  tsuru-image: tsuru/api:latest
  install-dashboard: false
`, hosts)
}

func (s *S) getPlatforms() []string {
	availablePlatforms := []string{
		"tsuru/python",
		"tsuru/go",
		"tsuru/buildpack",
		"tsuru/cordova",
		"tsuru/elixir",
		"tsuru/java",
		"tsuru/nodejs",
		"tsuru/php",
		"tsuru/play",
		"tsuru/ruby",
		"tsuru/static",
		"tsuru/perl",
	}
	if _, ok := os.LookupEnv(integrationEnvID + "platforms"); !ok {
		return availablePlatforms
	}
	envPlatforms := s.env.All("platforms")
	selectedPlatforms := make([]string, 0, len(availablePlatforms))
	for _, name := range envPlatforms {
		name = strings.Trim(name, " ")
		for i, platform := range availablePlatforms {
			if name == platform || "tsuru/"+name == platform {
				selectedPlatforms = append(selectedPlatforms, platform)
				availablePlatforms = append(availablePlatforms[:i], availablePlatforms[i+1:]...)
				break
			}
		}
	}
	return selectedPlatforms
}

func (s *S) getProvisioners() []string {
	availableProvisioners := []string{"docker"}
	if _, ok := os.LookupEnv(integrationEnvID + "provisioners"); !ok {
		return availableProvisioners
	}
	selectedProvisioners := make([]string, 0, len(availableProvisioners))
	for _, provisioner := range s.env.All("provisioners") {
		provisioner = strings.Trim(provisioner, " ")
		for i, item := range availableProvisioners {
			if item == provisioner {
				selectedProvisioners = append(selectedProvisioners, provisioner)
				availableProvisioners = append(availableProvisioners[:i], availableProvisioners[i+1:]...)
				break
			}
		}
	}
	return selectedProvisioners
}

func (s *S) getClusterManagers(c *check.C) []ClusterManager {
	availableClusterManagers := map[string]ClusterManager{
		"minikube": &MinikubeClusterManager{env: s.env},
		"kubectl": &KubectlClusterManager{
			env:     s.env,
			config:  s.env.Get("kubectlconfig"),
			context: s.env.Get("kubectlctx"),
			binary:  s.env.Get("kubectlbinary"),
		},
		"kubeenv": &KubeenvClusterManager{
			env: s.env,
		},
	}
	managers := make([]ClusterManager, 0, len(availableClusterManagers))
	clusters := s.env.All("clusters")
	for _, cluster := range clusters {
		cluster = strings.Trim(cluster, " ")
		manager := availableClusterManagers[cluster]
		if manager == nil {
			continue
		}
		managers = append(managers, manager)
	}
	return managers
}

func installerName(env *Environment) string {
	name := env.Get("installername")
	if name == "" {
		name = "tsuru"
	}
	return name
}

func (s *S) config(c *check.C) {
	env := NewEnvironment()
	if !env.Has("enabled") {
		return
	}
	s.env = env
	platforms = s.getPlatforms()
	provisioners = s.getProvisioners()
	clusterManagers = s.getClusterManagers(c)
	installerConfig = s.getInstallerConfig()
}
<commit_msg>integrations: Drop buildpack temporally<commit_after>// Copyright 2017 tsuru 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 integration

import (
	"fmt"
	"os"
	"strings"

	check "gopkg.in/check.v1"
)

func (s *S) getInstallerConfig() string {
	hosts := len(provisioners)
	for _, m := range clusterManagers {
		if req, ok := m.(interface {
			RequiredNodes() int
		}); ok {
			hosts += req.RequiredNodes()
		}
	}
	// if no host is set, add one, so Tsuru can build platforms
	if hosts == 0 {
		hosts = 1
	}
	return fmt.Sprintf(`driver:
  name: virtualbox
  options:
    virtualbox-cpu-count: 2
    virtualbox-memory: 2048
docker-flags:
  - experimental
hosts:
  apps:
    size: %d
components:
  tsuru-image: tsuru/api:latest
  install-dashboard: false
`, hosts)
}

func (s *S) getPlatforms() []string {
	availablePlatforms := []string{
		"tsuru/python",
		"tsuru/go",
		"tsuru/cordova",
		"tsuru/elixir",
		"tsuru/java",
		"tsuru/nodejs",
		"tsuru/php",
		"tsuru/play",
		"tsuru/ruby",
		"tsuru/static",
		"tsuru/perl",
	}
	if _, ok := os.LookupEnv(integrationEnvID + "platforms"); !ok {
		return availablePlatforms
	}
	envPlatforms := s.env.All("platforms")
	selectedPlatforms := make([]string, 0, len(availablePlatforms))
	for _, name := range envPlatforms {
		name = strings.Trim(name, " ")
		for i, platform := range availablePlatforms {
			if name == platform || "tsuru/"+name == platform {
				selectedPlatforms = append(selectedPlatforms, platform)
				availablePlatforms = append(availablePlatforms[:i], availablePlatforms[i+1:]...)
				break
			}
		}
	}
	return selectedPlatforms
}

func (s *S) getProvisioners() []string {
	availableProvisioners := []string{"docker"}
	if _, ok := os.LookupEnv(integrationEnvID + "provisioners"); !ok {
		return availableProvisioners
	}
	selectedProvisioners := make([]string, 0, len(availableProvisioners))
	for _, provisioner := range s.env.All("provisioners") {
		provisioner = strings.Trim(provisioner, " ")
		for i, item := range availableProvisioners {
			if item == provisioner {
				selectedProvisioners = append(selectedProvisioners, provisioner)
				availableProvisioners = append(availableProvisioners[:i], availableProvisioners[i+1:]...)
				break
			}
		}
	}
	return selectedProvisioners
}

func (s *S) getClusterManagers(c *check.C) []ClusterManager {
	availableClusterManagers := map[string]ClusterManager{
		"minikube": &MinikubeClusterManager{env: s.env},
		"kubectl": &KubectlClusterManager{
			env:     s.env,
			config:  s.env.Get("kubectlconfig"),
			context: s.env.Get("kubectlctx"),
			binary:  s.env.Get("kubectlbinary"),
		},
		"kubeenv": &KubeenvClusterManager{
			env: s.env,
		},
	}
	managers := make([]ClusterManager, 0, len(availableClusterManagers))
	clusters := s.env.All("clusters")
	for _, cluster := range clusters {
		cluster = strings.Trim(cluster, " ")
		manager := availableClusterManagers[cluster]
		if manager == nil {
			continue
		}
		managers = append(managers, manager)
	}
	return managers
}

func installerName(env *Environment) string {
	name := env.Get("installername")
	if name == "" {
		name = "tsuru"
	}
	return name
}

func (s *S) config(c *check.C) {
	env := NewEnvironment()
	if !env.Has("enabled") {
		return
	}
	s.env = env
	platforms = s.getPlatforms()
	provisioners = s.getProvisioners()
	clusterManagers = s.getClusterManagers(c)
	installerConfig = s.getInstallerConfig()
}
<|endoftext|>


<commit_before>package logreg

import "testing"

func TestNewLogisticRegression(t *testing.T) {
	if lr := NewLogisticRegression(); lr == nil {
		t.Errorf("got nil linear regression")
	}
}

func TestInitialize(t *testing.T) {
	lr := NewLogisticRegression()
	lr.Initialize()

	if len(lr.Xn) != len(lr.Yn) {
		t.Errorf("got different size of vectors Xn Yn, wants same size")
	}

	if len(lr.Xn[0]) != len(lr.Wn) {
		t.Errorf("got different size of vectors Xn Wn, wants same size")
	}

	if len(lr.Xn) != lr.TrainingPoints {
		t.Errorf("got different size of vectors Xn and training points, wants same number")
	}

	for i := 0; i < len(lr.Xn); i++ {
		for j := 0; j < len(lr.Xn[0]); j++ {
			if lr.Xn[i][j] < lr.Interval.Min ||
				lr.Xn[i][j] > lr.Interval.Max {
				t.Errorf("got value of Xn[%d][%d] = %v, want it between %v and %v", i, j, lr.Xn[i][j], lr.Interval.Min, lr.Interval.Max)
			}
		}
	}

	for i := 0; i < len(lr.Yn); i++ {
		if lr.Yn[i] != float64(-1) && lr.Yn[i] != float64(1) {
			t.Errorf("got value of Yn[%v] = %v, want it equal to -1 or 1", i, lr.Yn[i])
		}
	}
}

func TestInitializeFromData(t *testing.T) {
	data := [][]float64{
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
	}

	lr := NewLogisticRegression()
	if err := lr.InitializeFromData(data); err != nil {
		t.Errorf("%v", err)
	}
	if len(lr.Xn) != len(data) || len(lr.Yn) != len(data) {
		t.Errorf("got difference in size of Xn or Yn and data")
	}

	if len(lr.Xn) != lr.TrainingPoints {
		t.Errorf("got difference in size of Xn or TrainingPoints and data")
	}

	if len(lr.Xn[0]) != len(lr.Wn) {
		t.Errorf("got different size of vectors Xn Wn, wants same size")
	}

	if len(lr.Xn[0]) != lr.VectorSize || len(data[0]) != lr.VectorSize {
		t.Errorf("got difference in size of Xn[0] or data[0] with VectorSize")
	}
}

func TestLearn(t *testing.T) {
	lr := NewLogisticRegression()
	data := [][]float64{
		{0.1, 1, 1},
		{0.2, 1, 1},
		{0.3, 1, 1},
		{1, 0.5, -1},
		{1, 0.6, -1},
		{1, 0.7, -1},
	}

	lr.InitializeFromData(data)
	lr.Learn()
	expectedWn := []float64{0.06586, -0.99194, 0.56851}
	if !equal(expectedWn, lr.Wn) {
		t.Errorf("Weight vector is not correct: got %v, want %v", lr.Wn, expectedWn)
	}
}

func TestGradient(t *testing.T) {
	tests := []struct {
		w    []float64
		y    float64
		wn   []float64
		want []float64
	}{
		{
			w:    []float64{0, 0, 0},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, 0, 0, 0},
		},
		{
			w:    []float64{1, 0, 0},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, -0.5, 0, 0},
		},
		{
			w:    []float64{1, 1, 0},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, -0.5, -0.5, 0},
		},
		{
			w:    []float64{1, 1, 1},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, -0.5, -0.5, -0.5},
		},
	}
	for i, tt := range tests {
		lr := NewLogisticRegression()
		lr.Wn = tt.wn
		got := lr.Gradient(tt.w, tt.y)
		if !equal(got, tt.want) {
			t.Errorf("test %i: got Gradient = %v, want %v", i, got, tt.want)
		}
	}
}

func TestUpdateWeights(t *testing.T) {
	lr := NewLogisticRegression()
	lr.Eta = 0.1
	lr.Wn = []float64{1, 1, 1}
	gv := []float64{1, 1, 1}

	lr.UpdateWeights(gv)
	got := lr.Wn
	want := []float64{0.9, 0.9, 0.9}
	if !equal(got, want) {
		t.Errorf("got Wn:%v, want %v", got, want)
	}
}

const epsilon float64 = 0.001

func equal(a, b []float64) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if (a[i] - b[i]) > epsilon {
			return false
		}
	}
	return true
}
<commit_msg>logreg - make test table for update weights<commit_after>package logreg

import "testing"

func TestNewLogisticRegression(t *testing.T) {
	if lr := NewLogisticRegression(); lr == nil {
		t.Errorf("got nil linear regression")
	}
}

func TestInitialize(t *testing.T) {
	lr := NewLogisticRegression()
	lr.Initialize()

	if len(lr.Xn) != len(lr.Yn) {
		t.Errorf("got different size of vectors Xn Yn, wants same size")
	}

	if len(lr.Xn[0]) != len(lr.Wn) {
		t.Errorf("got different size of vectors Xn Wn, wants same size")
	}

	if len(lr.Xn) != lr.TrainingPoints {
		t.Errorf("got different size of vectors Xn and training points, wants same number")
	}

	for i := 0; i < len(lr.Xn); i++ {
		for j := 0; j < len(lr.Xn[0]); j++ {
			if lr.Xn[i][j] < lr.Interval.Min ||
				lr.Xn[i][j] > lr.Interval.Max {
				t.Errorf("got value of Xn[%d][%d] = %v, want it between %v and %v", i, j, lr.Xn[i][j], lr.Interval.Min, lr.Interval.Max)
			}
		}
	}

	for i := 0; i < len(lr.Yn); i++ {
		if lr.Yn[i] != float64(-1) && lr.Yn[i] != float64(1) {
			t.Errorf("got value of Yn[%v] = %v, want it equal to -1 or 1", i, lr.Yn[i])
		}
	}
}

func TestInitializeFromData(t *testing.T) {
	data := [][]float64{
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
		{1, 1, 1},
	}

	lr := NewLogisticRegression()
	if err := lr.InitializeFromData(data); err != nil {
		t.Errorf("%v", err)
	}
	if len(lr.Xn) != len(data) || len(lr.Yn) != len(data) {
		t.Errorf("got difference in size of Xn or Yn and data")
	}

	if len(lr.Xn) != lr.TrainingPoints {
		t.Errorf("got difference in size of Xn or TrainingPoints and data")
	}

	if len(lr.Xn[0]) != len(lr.Wn) {
		t.Errorf("got different size of vectors Xn Wn, wants same size")
	}

	if len(lr.Xn[0]) != lr.VectorSize || len(data[0]) != lr.VectorSize {
		t.Errorf("got difference in size of Xn[0] or data[0] with VectorSize")
	}
}

func TestLearn(t *testing.T) {
	lr := NewLogisticRegression()
	data := [][]float64{
		{0.1, 1, 1},
		{0.2, 1, 1},
		{0.3, 1, 1},
		{1, 0.5, -1},
		{1, 0.6, -1},
		{1, 0.7, -1},
	}

	lr.InitializeFromData(data)
	lr.Learn()
	expectedWn := []float64{0.06586, -0.99194, 0.56851}
	if !equal(expectedWn, lr.Wn) {
		t.Errorf("Weight vector is not correct: got %v, want %v", lr.Wn, expectedWn)
	}
}

func TestGradient(t *testing.T) {
	tests := []struct {
		w    []float64
		y    float64
		wn   []float64
		want []float64
	}{
		{
			w:    []float64{0, 0, 0},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, 0, 0, 0},
		},
		{
			w:    []float64{1, 0, 0},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, -0.5, 0, 0},
		},
		{
			w:    []float64{1, 1, 0},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, -0.5, -0.5, 0},
		},
		{
			w:    []float64{1, 1, 1},
			y:    1,
			wn:   []float64{0, 0, 0, 0},
			want: []float64{-0.5, -0.5, -0.5, -0.5},
		},
	}
	for i, tt := range tests {
		lr := NewLogisticRegression()
		lr.Wn = tt.wn
		got := lr.Gradient(tt.w, tt.y)
		if !equal(got, tt.want) {
			t.Errorf("test %i: got Gradient = %v, want %v", i, got, tt.want)
		}
	}
}

func TestUpdateWeights(t *testing.T) {
	tests := []struct {
		eta            float64
		w              []float64
		gradientVector []float64
		want           []float64
	}{
		{
			eta:            0.1,
			w:              []float64{1, 1, 1},
			gradientVector: []float64{1, 1, 1},
			want:           []float64{0.9, 0.9, 0.9},
		},
	}

	for i, tt := range tests {
		lr := NewLogisticRegression()
		lr.Eta = tt.eta
		lr.Wn = tt.w
		lr.UpdateWeights(tt.gradientVector)
		got := lr.Wn
		if !equal(got, tt.want) {
			t.Errorf("test %v: got Wn:%v, want %v", i, got, tt.want)
		}
	}
}

const epsilon float64 = 0.001

func equal(a, b []float64) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if (a[i] - b[i]) > epsilon {
			return false
		}
	}
	return true
}
<|endoftext|>


<commit_before>package wpa_dbus

import (
	"fmt"

	"github.com/mark2b/wpa-connect/internal/log"
	"github.com/godbus/dbus"
)

type InterfaceWPA struct {
	WPA              *WPA
	Object           dbus.BusObject
	Networks         []NetworkWPA
	BSSs             []BSSWPA
	State            string
	Scanning         bool
	Ifname           string
	CurrentBSS       *BSSWPA
	TempBSS          *BSSWPA
	CurrentNetwork   *NetworkWPA
	NewNetwork       *NetworkWPA
	ScanInterval     int32
	DisconnectReason int32
	SignalChannel    chan *dbus.Signal
	Error            error
}

func (self *InterfaceWPA) ReadNetworksList() *InterfaceWPA {
	if self.Error == nil {
		if networks, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.Networks", self.Object); err == nil {
			newNetworks := []NetworkWPA{}
			for _, networkObjectPath := range networks.([]dbus.ObjectPath) {
				network := NetworkWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", networkObjectPath)}
				newNetworks = append(newNetworks, network)
			}
			self.Networks = newNetworks
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) MakeTempBSS() *InterfaceWPA {
	self.TempBSS = &BSSWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", "/")}
	return self
}

func (self *InterfaceWPA) ReadBSSList() *InterfaceWPA {
	if self.Error == nil {
		if bsss, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.BSSs", self.Object); err == nil {
			newBSSs := []BSSWPA{}
			for _, bssObjectPath := range bsss.([]dbus.ObjectPath) {
				bss := BSSWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", bssObjectPath)}
				newBSSs = append(newBSSs, bss)
			}
			self.BSSs = newBSSs
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) Scan() *InterfaceWPA {
	if self.Error == nil {
		args := make(map[string]dbus.Variant, 0)
		args["Type"] = dbus.MakeVariant("passive")
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Scan", 0, args); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Disconnect() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Disconnect", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Reassociate() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Reassociate", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Reattach() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Reattach", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Reconnect() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Reconnect", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) RemoveAllNetworks() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.RemoveAllNetworks", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) AddNetwork(args map[string]dbus.Variant) *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.AddNetwork", 0, args); call.Err == nil {
			if len(call.Body) > 0 {
				networkObjectPath := call.Body[0].(dbus.ObjectPath)
				self.NewNetwork = &NetworkWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", networkObjectPath)}
			}
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadState() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.State", self.Object); err == nil {
			self.State = value.(string)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadScanning() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.Scanning", self.Object); err == nil {
			self.Scanning = value.(bool)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadIfname() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.Ifname", self.Object); err == nil {
			self.Ifname = value.(string)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadScanInterval() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.ScanInterval", self.Object); err == nil {
			self.ScanInterval = value.(int32)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadDisconnectReason() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.DisconnectReason", self.Object); err == nil {
			self.DisconnectReason = value.(int32)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) AddSignalsObserver() *InterfaceWPA {
	log.Log.Debug("AddSignalsObserver.Interface")
	match := fmt.Sprintf("type='signal',interface='fi.w1.wpa_supplicant1.Interface',path='%s'", self.Object.Path())
	if call := self.WPA.Connection.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, match); call.Err == nil {
	} else {
		self.Error = call.Err
	}
	return self
}

func (self *InterfaceWPA) RemoveSignalsObserver() *InterfaceWPA {
	log.Log.Debug("RemoveSignalsObserver.Interface")
	match := fmt.Sprintf("type='signal',interface='fi.w1.wpa_supplicant1.Interface',path='%s'", self.Object.Path())
	if call := self.WPA.Connection.BusObject().Call("org.freedesktop.DBus.RemoveMatch", 0, match); call.Err == nil {
	} else {
		self.Error = call.Err
	}
	return self
}
<commit_msg>add currentBSS and currentNetwork getter<commit_after>package wpa_dbus

import (
	"fmt"

	"github.com/godbus/dbus"
	"github.com/mark2b/wpa-connect/internal/log"
)

type InterfaceWPA struct {
	WPA              *WPA
	Object           dbus.BusObject
	Networks         []NetworkWPA
	BSSs             []BSSWPA
	State            string
	Scanning         bool
	Ifname           string
	CurrentBSS       *BSSWPA
	TempBSS          *BSSWPA
	CurrentNetwork   *NetworkWPA
	NewNetwork       *NetworkWPA
	ScanInterval     int32
	DisconnectReason int32
	SignalChannel    chan *dbus.Signal
	Error            error
}

func (self *InterfaceWPA) ReadNetworksList() *InterfaceWPA {
	if self.Error == nil {
		if networks, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.Networks", self.Object); err == nil {
			newNetworks := []NetworkWPA{}
			for _, networkObjectPath := range networks.([]dbus.ObjectPath) {
				network := NetworkWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", networkObjectPath)}
				newNetworks = append(newNetworks, network)
			}
			self.Networks = newNetworks
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) MakeTempBSS() *InterfaceWPA {
	self.TempBSS = &BSSWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", "/")}
	return self
}

func (self *InterfaceWPA) ReadBSSList() *InterfaceWPA {
	if self.Error == nil {
		if bsss, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.BSSs", self.Object); err == nil {
			newBSSs := []BSSWPA{}
			for _, bssObjectPath := range bsss.([]dbus.ObjectPath) {
				bss := BSSWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", bssObjectPath)}
				newBSSs = append(newBSSs, bss)
			}
			self.BSSs = newBSSs
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) Scan() *InterfaceWPA {
	if self.Error == nil {
		args := make(map[string]dbus.Variant, 0)
		args["Type"] = dbus.MakeVariant("passive")
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Scan", 0, args); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Disconnect() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Disconnect", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Reassociate() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Reassociate", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Reattach() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Reattach", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) Reconnect() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.Reconnect", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) RemoveAllNetworks() *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.RemoveAllNetworks", 0); call.Err == nil {
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) AddNetwork(args map[string]dbus.Variant) *InterfaceWPA {
	if self.Error == nil {
		if call := self.Object.Call("fi.w1.wpa_supplicant1.Interface.AddNetwork", 0, args); call.Err == nil {
			if len(call.Body) > 0 {
				networkObjectPath := call.Body[0].(dbus.ObjectPath)
				self.NewNetwork = &NetworkWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", networkObjectPath)}
			}
		} else {
			self.Error = call.Err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadState() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.State", self.Object); err == nil {
			self.State = value.(string)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadScanning() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.Scanning", self.Object); err == nil {
			self.Scanning = value.(bool)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadIfname() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.Ifname", self.Object); err == nil {
			self.Ifname = value.(string)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadScanInterval() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.ScanInterval", self.Object); err == nil {
			self.ScanInterval = value.(int32)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadDisconnectReason() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.DisconnectReason", self.Object); err == nil {
			self.DisconnectReason = value.(int32)
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) AddSignalsObserver() *InterfaceWPA {
	log.Log.Debug("AddSignalsObserver.Interface")
	match := fmt.Sprintf("type='signal',interface='fi.w1.wpa_supplicant1.Interface',path='%s'", self.Object.Path())
	if call := self.WPA.Connection.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, match); call.Err == nil {
	} else {
		self.Error = call.Err
	}
	return self
}

func (self *InterfaceWPA) RemoveSignalsObserver() *InterfaceWPA {
	log.Log.Debug("RemoveSignalsObserver.Interface")
	match := fmt.Sprintf("type='signal',interface='fi.w1.wpa_supplicant1.Interface',path='%s'", self.Object.Path())
	if call := self.WPA.Connection.BusObject().Call("org.freedesktop.DBus.RemoveMatch", 0, match); call.Err == nil {
	} else {
		self.Error = call.Err
	}
	return self
}

func (self *InterfaceWPA) ReadCurrentBSS() *InterfaceWPA {
	if self.Error == nil {
		if value, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.CurrentBSS", self.Object); err == nil {
			bssObjectPath := value.(dbus.ObjectPath)
			self.CurrentBSS = &BSSWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", bssObjectPath)}
		} else {
			self.Error = err
		}
	}
	return self
}

func (self *InterfaceWPA) ReadCurrentNetwork() *InterfaceWPA {
	if self.Error == nil {
		if network, err := self.WPA.get("fi.w1.wpa_supplicant1.Interface.CurrentNetwork", self.Object); err == nil {
			networkObjectPath := network.(dbus.ObjectPath)
			self.CurrentNetwork = &NetworkWPA{Interface: self, Object: self.WPA.Connection.Object("fi.w1.wpa_supplicant1", networkObjectPath)}
		} else {
			self.Error = err
		}
	}
	return self
}
<|endoftext|>


<commit_before>package main

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

	"github.com/lxc/lxd/lxd/cluster"
	"github.com/lxc/lxd/lxd/db"
	"github.com/lxc/lxd/lxd/db/query"
	"github.com/lxc/lxd/lxd/state"
	"github.com/lxc/lxd/lxd/util"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/version"
	"github.com/pkg/errors"
)

func containersGet(d *Daemon, r *http.Request) Response {
	for i := 0; i < 100; i++ {
		result, err := doContainersGet(d, r)
		if err == nil {
			return SyncResponse(true, result)
		}
		if !query.IsRetriableError(err) {
			logger.Debugf("DBERR: containersGet: error %q", err)
			return SmartError(err)
		}
		// 1 s may seem drastic, but we really don't want to thrash
		// perhaps we should use a random amount
		time.Sleep(100 * time.Millisecond)
	}

	logger.Debugf("DBERR: containersGet, db is locked")
	logger.Debugf(logger.GetStack())
	return InternalError(fmt.Errorf("DB is locked"))
}

func doContainersGet(d *Daemon, r *http.Request) (interface{}, error) {
	var result map[string][]string // Containers by node address
	var nodes map[string]string    // Node names by container
	err := d.cluster.Transaction(func(tx *db.ClusterTx) error {
		var err error

		result, err = tx.ContainersListByNodeAddress()
		if err != nil {
			return err
		}

		nodes, err = tx.ContainersByNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return []string{}, err
	}

	recursion := util.IsRecursionRequest(r)
	resultString := []string{}
	resultList := []*api.Container{}
	resultMu := sync.Mutex{}

	resultAppend := func(name string, c api.Container, err error) {
		if err != nil {
			c = api.Container{
				Name:       name,
				Status:     api.Error.String(),
				StatusCode: api.Error,
				Location:   nodes[name],
			}
		}
		resultMu.Lock()
		resultList = append(resultList, &c)
		resultMu.Unlock()
	}

	wg := sync.WaitGroup{}
	for address, containers := range result {
		// If this is an internal request from another cluster node,
		// ignore containers from other nodes, and return only the ones
		// on this node
		if isClusterNotification(r) && address != "" {
			continue
		}

		// Mark containers on unavailable nodes as down
		if recursion && address == "0.0.0.0" {
			for _, container := range containers {
				resultAppend(container, api.Container{}, fmt.Errorf("unavailable"))
			}

			continue
		}

		// For recursion requests we need to fetch the state of remote
		// containers from their respective nodes.
		if recursion && address != "" && !isClusterNotification(r) {
			wg.Add(1)
			go func(address string, containers []string) {
				defer wg.Done()
				cert := d.endpoints.NetworkCert()

				cs, err := doContainersGetFromNode(address, cert)
				if err != nil {
					for _, name := range containers {
						resultAppend(name, api.Container{}, err)
					}

					return
				}

				for _, c := range cs {
					resultAppend(c.Name, c, nil)
				}
			}(address, containers)

			continue
		}

		for _, container := range containers {
			if !recursion {
				url := fmt.Sprintf("/%s/containers/%s", version.APIVersion, container)
				resultString = append(resultString, url)
				continue
			}

			c, err := doContainerGet(d.State(), container)
			if err != nil {
				resultAppend(container, api.Container{}, err)
			} else {
				resultAppend(container, *c, err)
			}
		}
	}
	wg.Wait()

	if !recursion {
		return resultString, nil
	}

	// Sort the result list by name.
	sort.Slice(resultList, func(i, j int) bool {
		return resultList[i].Name < resultList[j].Name
	})

	return resultList, nil
}

func doContainerGet(s *state.State, cname string) (*api.Container, error) {
	c, err := containerLoadByName(s, cname)
	if err != nil {
		return nil, err
	}

	cts, _, err := c.Render()
	if err != nil {
		return nil, err
	}

	return cts.(*api.Container), nil
}

// Fetch information about the containers on the given remote node, using the
// rest API and with a timeout of 30 seconds.
func doContainersGetFromNode(node string, cert *shared.CertInfo) ([]api.Container, error) {
	f := func() ([]api.Container, error) {
		client, err := cluster.Connect(node, cert, true)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to connect to node %s", node)
		}
		containers, err := client.GetContainers()
		if err != nil {
			return nil, errors.Wrapf(err, "failed to get containers from node %s", node)
		}
		return containers, nil
	}

	timeout := time.After(30 * time.Second)
	done := make(chan struct{})

	var containers []api.Container
	var err error

	go func() {
		containers, err = f()
		done <- struct{}{}
	}()

	select {
	case <-timeout:
		err = fmt.Errorf("timeout getting containers from node %s", node)
	case <-done:
	}

	return containers, err
}
<commit_msg>lxd/containers: Speed up recursive list<commit_after>package main

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

	"github.com/lxc/lxd/lxd/cluster"
	"github.com/lxc/lxd/lxd/db"
	"github.com/lxc/lxd/lxd/db/query"
	"github.com/lxc/lxd/lxd/util"
	"github.com/lxc/lxd/shared"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/version"
	"github.com/pkg/errors"
)

func containersGet(d *Daemon, r *http.Request) Response {
	for i := 0; i < 100; i++ {
		result, err := doContainersGet(d, r)
		if err == nil {
			return SyncResponse(true, result)
		}
		if !query.IsRetriableError(err) {
			logger.Debugf("DBERR: containersGet: error %q", err)
			return SmartError(err)
		}
		// 1 s may seem drastic, but we really don't want to thrash
		// perhaps we should use a random amount
		time.Sleep(100 * time.Millisecond)
	}

	logger.Debugf("DBERR: containersGet, db is locked")
	logger.Debugf(logger.GetStack())
	return InternalError(fmt.Errorf("DB is locked"))
}

func doContainersGet(d *Daemon, r *http.Request) (interface{}, error) {
	recursion := util.IsRecursionRequest(r)
	resultString := []string{}
	resultList := []*api.Container{}
	resultMu := sync.Mutex{}

	// Get the list and location of all containers
	var result map[string][]string // Containers by node address
	var nodes map[string]string    // Node names by container
	err := d.cluster.Transaction(func(tx *db.ClusterTx) error {
		var err error

		result, err = tx.ContainersListByNodeAddress()
		if err != nil {
			return err
		}

		nodes, err = tx.ContainersByNodeName()
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return []string{}, err
	}

	// Get the local containers
	nodeCts := map[string]container{}
	if recursion {
		cts, err := containerLoadNodeAll(d.State())
		if err != nil {
			return nil, err
		}

		for _, ct := range cts {
			nodeCts[ct.Name()] = ct
		}
	}

	resultAppend := func(name string, c api.Container, err error) {
		if err != nil {
			c = api.Container{
				Name:       name,
				Status:     api.Error.String(),
				StatusCode: api.Error,
				Location:   nodes[name],
			}
		}
		resultMu.Lock()
		resultList = append(resultList, &c)
		resultMu.Unlock()
	}

	wg := sync.WaitGroup{}
	for address, containers := range result {
		// If this is an internal request from another cluster node,
		// ignore containers from other nodes, and return only the ones
		// on this node
		if isClusterNotification(r) && address != "" {
			continue
		}

		// Mark containers on unavailable nodes as down
		if recursion && address == "0.0.0.0" {
			for _, container := range containers {
				resultAppend(container, api.Container{}, fmt.Errorf("unavailable"))
			}

			continue
		}

		// For recursion requests we need to fetch the state of remote
		// containers from their respective nodes.
		if recursion && address != "" && !isClusterNotification(r) {
			wg.Add(1)
			go func(address string, containers []string) {
				defer wg.Done()
				cert := d.endpoints.NetworkCert()

				cs, err := doContainersGetFromNode(address, cert)
				if err != nil {
					for _, name := range containers {
						resultAppend(name, api.Container{}, err)
					}

					return
				}

				for _, c := range cs {
					resultAppend(c.Name, c, nil)
				}
			}(address, containers)

			continue
		}

		for _, container := range containers {
			if !recursion {
				url := fmt.Sprintf("/%s/containers/%s", version.APIVersion, container)
				resultString = append(resultString, url)
				continue
			}

			c, _, err := nodeCts[container].Render()
			if err != nil {
				resultAppend(container, api.Container{}, err)
			} else {
				resultAppend(container, *c.(*api.Container), err)
			}
		}
	}
	wg.Wait()

	if !recursion {
		return resultString, nil
	}

	// Sort the result list by name.
	sort.Slice(resultList, func(i, j int) bool {
		return resultList[i].Name < resultList[j].Name
	})

	return resultList, nil
}

// Fetch information about the containers on the given remote node, using the
// rest API and with a timeout of 30 seconds.
func doContainersGetFromNode(node string, cert *shared.CertInfo) ([]api.Container, error) {
	f := func() ([]api.Container, error) {
		client, err := cluster.Connect(node, cert, true)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to connect to node %s", node)
		}
		containers, err := client.GetContainers()
		if err != nil {
			return nil, errors.Wrapf(err, "failed to get containers from node %s", node)
		}
		return containers, nil
	}

	timeout := time.After(30 * time.Second)
	done := make(chan struct{})

	var containers []api.Container
	var err error

	go func() {
		containers, err = f()
		done <- struct{}{}
	}()

	select {
	case <-timeout:
		err = fmt.Errorf("timeout getting containers from node %s", node)
	case <-done:
	}

	return containers, err
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"davisputnam/clause"
	"davisputnam/clauseset"
	"davisputnam/connector"
	"fmt"
	"log"
	"os"
	"strings"
)

/*
def Satisfiable(CS):
    if CS = {}:
        return true
    if {} in CS:
        return false
    if {L} in CS:
        return Satisfiable(CS_L)
    select L in lit(CS)
        return Satisfiable(CS_L) | Satisfiable(CS_L')
*/

//Satisfiable implements above function
func Satisfiable(CS clauseset.ClauseSet) bool {
	fmt.Printf("\n%sSatisfiable(%s)\n", strings.Repeat(" ", CS.Indent), CS)
	CS.Indent += 2

	//if CS = {} : return true
	if CS.Len() == 0 {
		fmt.Printf("%sEmpty ClauseSet, returning true\n", strings.Repeat(" ", CS.Indent))
		return true
	}

	//if {} in CS : return false
	firstElement, err := CS.FirstElement()
	if err != nil {
		log.Fatal(err)
	}
	if clause.Len(firstElement) == 0 {
		fmt.Printf("%s{} found in ClauseSet, returning false\n", strings.Repeat(" ", CS.Indent))
		return false
	}

	//select L in lit(CS): return Satisfiable(CS_L) || Satisfiable(CS_L')
	nextLiteral, err2 := CS.NextLiteral()
	if err2 != nil {
		log.Fatal(err2)
	}

	fmt.Printf("%sSpliting on %s\n", strings.Repeat(" ", CS.Indent), nextLiteral)

	CSL := CS.Reduce(nextLiteral)
	CSL.Indent = CS.Indent
	CSR := CS.Reduce(nextLiteral.Negation())
	CSR.Indent = CS.Indent

	return Satisfiable(CSL) || Satisfiable(CSR)
}

//FindValidity finds the validity of the argument (given as a ClauseSet)
func FindValidity(CS clauseset.ClauseSet) {
	fmt.Printf("Starting ClauseSet: %s\n", CS)

	CS.Indent = 0
	sat := Satisfiable(CS)

	fmt.Print("Conclusion: ")
	if sat {
		fmt.Printf("Satisfiable(%s) == %t; INVALID\n", CS, sat)
	} else {
		fmt.Printf("Satisfiable(%s) == %t; VALID\n", CS, sat)
	}
}

//ConstructCS reads in premisies from a file and returns its ClauseSet
func ConstructCS(file string) clauseset.ClauseSet {
	newCS := clauseset.ClauseSet{}

	infile, err := os.Open(file)
	if err != nil {
		panic(err)
	}
	defer infile.Close()
	scanner := bufio.NewScanner(infile)
	scanner.Split(bufio.ScanLines)
	scanner.Scan()
	contin := true
	for contin {
		line := scanner.Text()
		con := connector.Parse(line)
		con = con.ToCNF()
		if !scanner.Scan() {
			con = con.Negate()
			con = con.PropagateNegations()
			contin = false
		}
		cs := clauseset.ConstructCS(con)
		newCS = clauseset.Combine(newCS, cs)
	}

	return newCS
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Useage: go dp.go <input file>")
		os.Exit(0)
	}
	CS := ConstructCS(os.Args[1])
	fmt.Println(CS)
	FindValidity(CS)

}
<commit_msg>initial parsing of wolfram api for cnf conversions<commit_after>package main

import (
	"bufio"
	"davisputnam/clause"
	"davisputnam/clauseset"
	//"davisputnam/connector"
	"fmt"
	"log"
	"os"
	"strings"
	"net/http"
	"io/ioutil"
	"regexp"
)

/*
def Satisfiable(CS):
    if CS = {}:
        return true
    if {} in CS:
        return false
    if {L} in CS:
        return Satisfiable(CS_L)
    select L in lit(CS)
        return Satisfiable(CS_L) | Satisfiable(CS_L')
*/

//Satisfiable implements above function
func Satisfiable(CS clauseset.ClauseSet) bool {
	fmt.Printf("\n%sSatisfiable(%s)\n", strings.Repeat(" ", CS.Indent), CS)
	CS.Indent += 2

	//if CS = {} : return true
	if CS.Len() == 0 {
		fmt.Printf("%sEmpty ClauseSet, returning true\n", strings.Repeat(" ", CS.Indent))
		return true
	}

	//if {} in CS : return false
	firstElement, err := CS.FirstElement()
	if err != nil {
		log.Fatal(err)
	}
	if clause.Len(firstElement) == 0 {
		fmt.Printf("%s{} found in ClauseSet, returning false\n", strings.Repeat(" ", CS.Indent))
		return false
	}

	//select L in lit(CS): return Satisfiable(CS_L) || Satisfiable(CS_L')
	nextLiteral, err2 := CS.NextLiteral()
	if err2 != nil {
		log.Fatal(err2)
	}

	fmt.Printf("%sSpliting on %s\n", strings.Repeat(" ", CS.Indent), nextLiteral)

	CSL := CS.Reduce(nextLiteral)
	CSL.Indent = CS.Indent
	CSR := CS.Reduce(nextLiteral.Negation())
	CSR.Indent = CS.Indent

	return Satisfiable(CSL) || Satisfiable(CSR)
}

//FindValidity finds the validity of the argument (given as a ClauseSet)
func FindValidity(CS clauseset.ClauseSet) {
	fmt.Printf("Starting ClauseSet: %s\n", CS)

	CS.Indent = 0
	sat := Satisfiable(CS)

	fmt.Print("Conclusion: ")
	if sat {
		fmt.Printf("Satisfiable(%s) == %t; INVALID\n", CS, sat)
	} else {
		fmt.Printf("Satisfiable(%s) == %t; VALID\n", CS, sat)
	}
}

func clean(sentence string) string {
	result := strings.Replace(sentence, "<->", "+xnor+", -1)
	result = strings.Replace(result, "->", "+implies+", -1)
	result = strings.Replace(result, "v", "+or+", -1)
	result = strings.Replace(result, "^", "+and+", -1)
	result = strings.Replace(result, "~", "+not+", -1)
	return result
}

func getCNF(sentence string) clause.Clause {
	c := clause.Clause{}
	url := fmt.Sprintf("http://api.wolframalpha.com/v1/query?input=BooleanConvert[%s,%%22CNF%%22]&appid=2Y4TEV-W2AETK4T5K", clean(sentence))
	fmt.Println(url)
	response, err := http.Get(url)
	if err != nil {
        fmt.Printf("%s", err)
        os.Exit(1)
    } else {
        defer response.Body.Close()
        contents, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Printf("%s", err)
            os.Exit(1)
        }
        //fmt.Printf("%s\n", string(contents))
		lines := strings.Split(string(contents), "\n")
		found_first := false

		for _, line := range lines {
			//fmt.Printf("%q\n", line)
			if strings.Contains(line, "<plaintext>") {
				if !found_first {
					found_first = true
				}else{
					//fmt.Println(line)
					//r, _ := regexp.Compile(">([A-Z\\(\\)\\s]+)<")
					re := regexp.MustCompile("<plaintext>(.*)</plaintext>")
					cnf := re.FindStringSubmatch(line)[1]
					fmt.Printf("cnf: %s\n", cnf)
					break
				}
			}
		}
    }

	return c
}

//ConstructCS reads in premisies from a file and returns its ClauseSet
func ConstructCS(file string) clauseset.ClauseSet {
	newCS := clauseset.ClauseSet{}

	infile, err := os.Open(file)
	if err != nil {
		panic(err)
	}
	defer infile.Close()
	scanner := bufio.NewScanner(infile)
	scanner.Split(bufio.ScanLines)
	scanner.Scan()
	contin := true
	for contin {
		line := scanner.Text()

		if !scanner.Scan() {
			line = fmt.Sprintf("~(%s)", line)
			contin = false
		}
		fmt.Println(line)

		c := getCNF(line)

		newCS.Append(c)
	}

	return newCS
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Useage: go dp.go <input file>")
		os.Exit(0)
	}
	CS := ConstructCS(os.Args[1])
	fmt.Println(CS)
	//FindValidity(CS)

}
<|endoftext|>


<commit_before>package mongo

import (
	"time"

	"h12.me/gspec/db/docker"
)

func New(t docker.T) (*docker.Container, error) {
	return docker.New(t, "mongo", 10*time.Second, func() (string, error) {
		return docker.Run("-d", "-P", "mongo")
	})
}
<commit_msg>create a mgo session instead of the container.<commit_after>package mongo

import (
	"time"

	"gopkg.in/mgo.v2"
	"h12.me/gspec/db/docker"
)

type Session struct {
	mgoSession
	c *docker.Container
}
type mgoSession struct {
	*mgo.Session
}

func (s *Session) Close() {
	s.Session.Close()
	s.c.Close()
}

func New(t docker.T) (*Session, error) {
	container, err := docker.New(t, "mongo", 10*time.Second, func() (string, error) {
		return docker.Run("-d", "-P", "mongo")
	})
	if err != nil {
		return nil, err
	}

	session, err := mgo.Dial(container.Addr.String())
	if err != nil {
		return nil, err
	}
	return &Session{mgoSession{session}, container}, nil
}
<|endoftext|>