<commit_before>package memio

import (
	"io"
	"testing"
)

var (
	_ io.Reader     = new(ReadMem)
	_ io.Closer     = new(ReadMem)
	_ io.Seeker     = new(ReadMem)
	_ io.WriterTo   = new(ReadMem)
	_ io.ByteReader = new(ReadMem)
	_ io.ReaderAt   = new(ReadMem)

	_ io.Writer     = new(WriteMem)
	_ io.Closer     = new(WriteMem)
	_ io.Seeker     = new(WriteMem)
	_ io.ReaderFrom = new(WriteMem)
	_ io.ByteWriter = new(WriteMem)
	_ io.WriterAt   = new(WriteMem)
)

func TestRead(t *testing.T) {
	data := []byte("Hello, World!")
	reader := Open(data)
	toRead := make([]byte, 5)
	if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "Hello" {
		t.Errorf("expecting %q, got %q", "Hello", string(toRead))
		return
	}
	if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != ", Wor" {
		t.Errorf("expecting %q, got %q", ", Wor", string(toRead))
		return
	}
	if n, err := reader.Read(toRead); n != 3 {
		t.Errorf("expecting to read 3 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "ld!or" {
		t.Errorf("expecting %q, got %q", "ld!or", string(toRead))
		return
	}
	if n, err := reader.Read(toRead); n != 0 {
		t.Errorf("expecting to read 0 bytes, read %d", n)
		return
	} else if err != io.EOF {
		t.Errorf("expecting EOF")
	}
	if pos, err := reader.Seek(2, 0); pos != 2 {
		t.Errorf("expected to be at position 2, got %d", pos)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "llo, " {
		t.Errorf("expecting %q, got %q", "llo, ", string(toRead))
		return
	}
	if pos, err := reader.Seek(2, 1); pos != 9 {
		t.Errorf("expected to be at position 9, got %d", pos)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := reader.Read(toRead); n != 4 {
		t.Errorf("expecting to read 4 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "rld! " {
		t.Errorf("expecting %q, got %q", "rld! ", string(toRead))
		return
	}
	if pos, err := reader.Seek(-6, 2); pos != 7 {
		t.Errorf("expected to be at position 7, got %d", pos)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "World" {
		t.Errorf("expecting %q, got %q", "World", string(toRead))
		return
	}
	if _, err := reader.Seek(1, 0); err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	}
	reader.Close()
}

func TestWrite(t *testing.T) {
	data := []byte("Beep")
	writer := Create(&data)
	if n, err := writer.Write([]byte("J")); n != 1 {
		t.Errorf("expecting to write 1 byte, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Jeep" {
		t.Errorf("expecting %q, got %q", "Jeep", string(data))
		return
	}
	if n, err := writer.Write([]byte("ohn")); n != 3 {
		t.Errorf("expecting to write 3 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "John" {
		t.Errorf("expecting %q, got %q", "John", string(data))
		return
	}
	if n, err := writer.Write([]byte("ny")); n != 2 {
		t.Errorf("expecting to write 2 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Johnny" {
		t.Errorf("expecting %q, got %q", "Johnny", string(data))
		return
	}
	if pos, err := writer.Seek(0, 0); pos != 0 {
		t.Errorf("expected to be at position 0, got %d", pos)
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := writer.Write([]byte("Edmund")); n != 6 {
		t.Errorf("expecting to write 6 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Edmund" {
		t.Errorf("expecting %q, got %q", "Edmund", string(data))
		return
	}
	if pos, err := writer.Seek(-4, 2); pos != 2 {
		t.Errorf("expected to be at position 0, got %d", pos)
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := writer.Write([]byte("war")); n != 3 {
		t.Errorf("expecting to write 3 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Edward" {
		t.Errorf("expecting %q, got %q", "Edward", string(data))
		return
	}
	if pos, err := writer.Seek(1, 1); pos != 6 {
		t.Errorf("expected to be at position 6, got %d", pos)
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := writer.Write([]byte("o")); n != 1 {
		t.Errorf("expecting to write 1 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Edwardo" {
		t.Errorf("expecting %q, got %q", "Edwardo", string(data))
		return
	}
	writer.Close()
	_, err := writer.Seek(0, 0)
	if err != ErrClosed {
		t.Errorf("expecting close error")
		return
	}
	_, err = writer.Write([]byte("Beep"))
	if err != ErrClosed {
		t.Errorf("expecting close error")
		return
	}
}

func TestNewWrite(t *testing.T) {
	var data []byte
	writer := Create(&data)
	if n, err := writer.Write([]byte("Hello")); err != nil {
		t.Errorf("got error: %q", err.Error())
	} else if n != 5 {
		t.Errorf("expecting to write 5 bytes, wrote %d", n)
	} else if len(data) != 5 {
		t.Errorf("expecting buf to have 5 bytes, has %d", n)
	} else if string(data) != "Hello" {
		t.Errorf("expecting %q, got %q", "Hello", string(data))
	}
	if n, err := writer.Write([]byte("World")); err != nil {
		t.Errorf("got error: %q", err.Error())
	} else if n != 5 {
		t.Errorf("expecting to write 5 bytes, wrote %d", n)
	} else if len(data) != 10 {
		t.Errorf("expecting buf to have 5 bytes, has %d", n)
	} else if string(data) != "HelloWorld" {
		t.Errorf("expecting %q, got %q", "Hello", string(data))
	}
}

func TestReadFrom(t *testing.T) {
	data := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
	toRead := make([]byte, 0, 2480)
	for i := 0; i < 40; i++ {
		toRead = append(toRead, data...)
	}
	reader := Open(toRead)
	var toWrite []byte
	writer := Create(&toWrite)
	if n, err := writer.ReadFrom(reader); err != nil {
		t.Errorf("got error: %q", err.Error())
	} else if n != 2480 {
		t.Errorf("expecting to write 2480 bytes, wrote %d", n)
	} else if string(toRead) != string(toWrite) {
		t.Errorf("expecting %q, got %q", string(toRead), string(toWrite))
	}

}

func TestTruncate(t *testing.T) {
	data := make([]byte, 100)
	for i := byte(0); i < 100; i++ {
		data[i] = i % 10
	}
	w := Create(&data)
	w.Truncate(75)
	if len(data) != 75 {
		t.Errorf("expecting length 75, got %d", len(data))
		return
	}
	w.Truncate(90)
	if len(data) != 90 {
		t.Errorf("expecting length 90, got %d", len(data))
		return
	}
	for i := byte(0); i < 75; i++ {
		if data[i] != i%10 {
			t.Errorf("at position %d, expecting value of %d, got %d", i, i%10, data[i])
			return
		}
	}
	for i := byte(75); i < 90; i++ {
		if data[i] != 0 {
			t.Errorf("at position %d, expecting value of 0, got %d", i, data[i])
			return
		}
	}
	w.Truncate(100)
	if len(data) != 100 {
		t.Errorf("expecting length 100, got %d", len(data))
		return
	}
	for i := byte(90); i < 100; i++ {
		if data[i] != 0 {
			t.Errorf("at position %d, expecting value of 0, got %d", i, data[i])
			return
		}
	}
}
<commit_msg>changed var to const<commit_after>package memio

import (
	"io"
	"testing"
)

var (
	_ io.Reader     = new(ReadMem)
	_ io.Closer     = new(ReadMem)
	_ io.Seeker     = new(ReadMem)
	_ io.WriterTo   = new(ReadMem)
	_ io.ByteReader = new(ReadMem)
	_ io.ReaderAt   = new(ReadMem)

	_ io.Writer     = new(WriteMem)
	_ io.Closer     = new(WriteMem)
	_ io.Seeker     = new(WriteMem)
	_ io.ReaderFrom = new(WriteMem)
	_ io.ByteWriter = new(WriteMem)
	_ io.WriterAt   = new(WriteMem)
)

func TestRead(t *testing.T) {
	data := []byte("Hello, World!")
	reader := Open(data)
	toRead := make([]byte, 5)
	if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "Hello" {
		t.Errorf("expecting %q, got %q", "Hello", string(toRead))
		return
	}
	if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != ", Wor" {
		t.Errorf("expecting %q, got %q", ", Wor", string(toRead))
		return
	}
	if n, err := reader.Read(toRead); n != 3 {
		t.Errorf("expecting to read 3 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "ld!or" {
		t.Errorf("expecting %q, got %q", "ld!or", string(toRead))
		return
	}
	if n, err := reader.Read(toRead); n != 0 {
		t.Errorf("expecting to read 0 bytes, read %d", n)
		return
	} else if err != io.EOF {
		t.Errorf("expecting EOF")
	}
	if pos, err := reader.Seek(2, 0); pos != 2 {
		t.Errorf("expected to be at position 2, got %d", pos)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "llo, " {
		t.Errorf("expecting %q, got %q", "llo, ", string(toRead))
		return
	}
	if pos, err := reader.Seek(2, 1); pos != 9 {
		t.Errorf("expected to be at position 9, got %d", pos)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := reader.Read(toRead); n != 4 {
		t.Errorf("expecting to read 4 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "rld! " {
		t.Errorf("expecting %q, got %q", "rld! ", string(toRead))
		return
	}
	if pos, err := reader.Seek(-6, 2); pos != 7 {
		t.Errorf("expected to be at position 7, got %d", pos)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := reader.Read(toRead); n != 5 {
		t.Errorf("expecting to read 5 bytes, read %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(toRead) != "World" {
		t.Errorf("expecting %q, got %q", "World", string(toRead))
		return
	}
	if _, err := reader.Seek(1, 0); err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	}
	reader.Close()
}

func TestWrite(t *testing.T) {
	data := []byte("Beep")
	writer := Create(&data)
	if n, err := writer.Write([]byte("J")); n != 1 {
		t.Errorf("expecting to write 1 byte, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Jeep" {
		t.Errorf("expecting %q, got %q", "Jeep", string(data))
		return
	}
	if n, err := writer.Write([]byte("ohn")); n != 3 {
		t.Errorf("expecting to write 3 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "John" {
		t.Errorf("expecting %q, got %q", "John", string(data))
		return
	}
	if n, err := writer.Write([]byte("ny")); n != 2 {
		t.Errorf("expecting to write 2 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Johnny" {
		t.Errorf("expecting %q, got %q", "Johnny", string(data))
		return
	}
	if pos, err := writer.Seek(0, 0); pos != 0 {
		t.Errorf("expected to be at position 0, got %d", pos)
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := writer.Write([]byte("Edmund")); n != 6 {
		t.Errorf("expecting to write 6 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Edmund" {
		t.Errorf("expecting %q, got %q", "Edmund", string(data))
		return
	}
	if pos, err := writer.Seek(-4, 2); pos != 2 {
		t.Errorf("expected to be at position 0, got %d", pos)
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := writer.Write([]byte("war")); n != 3 {
		t.Errorf("expecting to write 3 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Edward" {
		t.Errorf("expecting %q, got %q", "Edward", string(data))
		return
	}
	if pos, err := writer.Seek(1, 1); pos != 6 {
		t.Errorf("expected to be at position 6, got %d", pos)
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if n, err := writer.Write([]byte("o")); n != 1 {
		t.Errorf("expecting to write 1 bytes, wrote %d", n)
		return
	} else if err != nil {
		t.Errorf("got error: %q", err.Error())
		return
	} else if string(data) != "Edwardo" {
		t.Errorf("expecting %q, got %q", "Edwardo", string(data))
		return
	}
	writer.Close()
	_, err := writer.Seek(0, 0)
	if err != ErrClosed {
		t.Errorf("expecting close error")
		return
	}
	_, err = writer.Write([]byte("Beep"))
	if err != ErrClosed {
		t.Errorf("expecting close error")
		return
	}
}

func TestNewWrite(t *testing.T) {
	var data []byte
	writer := Create(&data)
	if n, err := writer.Write([]byte("Hello")); err != nil {
		t.Errorf("got error: %q", err.Error())
	} else if n != 5 {
		t.Errorf("expecting to write 5 bytes, wrote %d", n)
	} else if len(data) != 5 {
		t.Errorf("expecting buf to have 5 bytes, has %d", n)
	} else if string(data) != "Hello" {
		t.Errorf("expecting %q, got %q", "Hello", string(data))
	}
	if n, err := writer.Write([]byte("World")); err != nil {
		t.Errorf("got error: %q", err.Error())
	} else if n != 5 {
		t.Errorf("expecting to write 5 bytes, wrote %d", n)
	} else if len(data) != 10 {
		t.Errorf("expecting buf to have 5 bytes, has %d", n)
	} else if string(data) != "HelloWorld" {
		t.Errorf("expecting %q, got %q", "Hello", string(data))
	}
}

func TestReadFrom(t *testing.T) {
	const data = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
	toRead := make([]byte, 0, 2480)
	for i := 0; i < 40; i++ {
		toRead = append(toRead, data...)
	}
	reader := Open(toRead)
	var toWrite []byte
	writer := Create(&toWrite)
	if n, err := writer.ReadFrom(reader); err != nil {
		t.Errorf("got error: %q", err.Error())
	} else if n != 2480 {
		t.Errorf("expecting to write 2480 bytes, wrote %d", n)
	} else if string(toRead) != string(toWrite) {
		t.Errorf("expecting %q, got %q", string(toRead), string(toWrite))
	}
}

func TestTruncate(t *testing.T) {
	data := make([]byte, 100)
	for i := byte(0); i < 100; i++ {
		data[i] = i % 10
	}
	w := Create(&data)
	w.Truncate(75)
	if len(data) != 75 {
		t.Errorf("expecting length 75, got %d", len(data))
		return
	}
	w.Truncate(90)
	if len(data) != 90 {
		t.Errorf("expecting length 90, got %d", len(data))
		return
	}
	for i := byte(0); i < 75; i++ {
		if data[i] != i%10 {
			t.Errorf("at position %d, expecting value of %d, got %d", i, i%10, data[i])
			return
		}
	}
	for i := byte(75); i < 90; i++ {
		if data[i] != 0 {
			t.Errorf("at position %d, expecting value of 0, got %d", i, data[i])
			return
		}
	}
	w.Truncate(100)
	if len(data) != 100 {
		t.Errorf("expecting length 100, got %d", len(data))
		return
	}
	for i := byte(90); i < 100; i++ {
		if data[i] != 0 {
			t.Errorf("at position %d, expecting value of 0, got %d", i, data[i])
			return
		}
	}
}
<|endoftext|>


<commit_before>package minimalweather

import (
	"encoding/json"
	"fmt"
	"log"
	"os"

	forecast "github.com/elcuervo/forecast/v2"
	"github.com/garyburd/redigo/redis"
)

const weather_prefix = "mw:weather:"

var api_key = os.Getenv("FORECAST_API_KEY")

type Weather struct {
	Coordinates Coordinates `json:"-"`

	Condition     string  `json:"condition"`
	Icon          string  `json:"icon"`
	Temperature   float64 `json:"temperature"`
	RainIntensity float64 `json:"rain_intensity"`
	BringUmbrella bool    `json:"bring_umbrella"`
}

func ClearWeatherCache() {
	pattern := fmt.Sprintf("%s*", weather_prefix)
	keys, err := redis.Values(c.Do("KEYS", pattern))

	if err != nil {
		log.Println(err)
	}

	for _, key := range keys {
		c.Do("DEL", key)
	}
}

func GetWeather(coords Coordinates) chan Weather {
	city_weather := make(chan Weather)
	key := fmt.Sprintf("%s%f,%f", weather_prefix, coords.Lat, coords.Lng)
	cached_weather, err := c.Do("GET", key)

	if err != nil {
		log.Println(err)
	}

	go func() {
		if cached_weather != nil {
			var weather Weather

			str, _ := redis.String(cached_weather, nil)
			bytes := []byte(str)
			json.Unmarshal(bytes, &weather)

			log.Printf("Loading weather: %f,%f\n",
				coords.Lat,
				coords.Lng)

			city_weather <- weather
		} else {
			var rain bool

			lat := fmt.Sprintf("%f", coords.Lat)
			lng := fmt.Sprintf("%f", coords.Lng)

			log.Printf("Checking weather: %s,%s\n", lat, lng)

			f, _ := forecast.Get(api_key, lat, lng, "now", forecast.SI)

			_, err := c.Do("HSET", "mw:stats", "forecast", f.APICalls)
			if err != nil {
				log.Println(err)
			}

			// Look for the next 8 hours. See if it's going to rain
			// at some point
			for _, cond := range f.Hourly.Data[:8] {
				rain = cond.PrecipIntensity > 0.1 || cond.PrecipProbability > 0.6
				if rain {
					break
				}
			}

			weather := &Weather{
				Coordinates:   coords,
				Condition:     f.Currently.Summary,
				Icon:          f.Currently.Icon,
				Temperature:   f.Currently.Temperature,
				RainIntensity: f.Currently.PrecipIntensity,
				BringUmbrella: rain}

			json_response, _ := json.Marshal(weather)
			_, err = c.Do("SETEX", key, 20*60, json_response)

			if err != nil {
				log.Println(err)
			}

			city_weather <- *weather
		}

	}()

	return city_weather
}
<commit_msg>Starts using apparent temperature<commit_after>package minimalweather

import (
	"encoding/json"
	"fmt"
	"log"
	"os"

	forecast "github.com/elcuervo/forecast/v2"
	"github.com/garyburd/redigo/redis"
)

const weather_prefix = "mw:weather:"

var api_key = os.Getenv("FORECAST_API_KEY")

type Weather struct {
	Coordinates Coordinates `json:"-"`

	Condition     string  `json:"condition"`
	Icon          string  `json:"icon"`
	Temperature   float64 `json:"temperature"`
	RainIntensity float64 `json:"rain_intensity"`
	BringUmbrella bool    `json:"bring_umbrella"`
}

func ClearWeatherCache() {
	pattern := fmt.Sprintf("%s*", weather_prefix)
	keys, err := redis.Values(c.Do("KEYS", pattern))

	if err != nil {
		log.Println(err)
	}

	for _, key := range keys {
		c.Do("DEL", key)
	}
}

func GetWeather(coords Coordinates) chan Weather {
	city_weather := make(chan Weather)
	key := fmt.Sprintf("%s%f,%f", weather_prefix, coords.Lat, coords.Lng)
	cached_weather, err := c.Do("GET", key)

	if err != nil {
		log.Println(err)
	}

	go func() {
		if cached_weather != nil {
			var weather Weather

			str, _ := redis.String(cached_weather, nil)
			bytes := []byte(str)
			json.Unmarshal(bytes, &weather)

			log.Printf("Loading weather: %f,%f\n",
				coords.Lat,
				coords.Lng)

			city_weather <- weather
		} else {
			var rain bool

			lat := fmt.Sprintf("%f", coords.Lat)
			lng := fmt.Sprintf("%f", coords.Lng)

			log.Printf("Checking weather: %s,%s\n", lat, lng)

			f, _ := forecast.Get(api_key, lat, lng, "now", forecast.SI)

			_, err := c.Do("HSET", "mw:stats", "forecast", f.APICalls)
			if err != nil {
				log.Println(err)
			}

			// Look for the next 8 hours. See if it's going to rain
			// at some point
			for _, cond := range f.Hourly.Data[:8] {
				rain = cond.PrecipIntensity > 0.1 || cond.PrecipProbability > 0.6
				if rain {
					break
				}
			}

			weather := &Weather{
				Coordinates:   coords,
				Condition:     f.Currently.Summary,
				Icon:          f.Currently.Icon,
				Temperature:   f.Currently.ApparentTemperature,
				RainIntensity: f.Currently.PrecipIntensity,
				BringUmbrella: rain}

			json_response, _ := json.Marshal(weather)
			_, err = c.Do("SETEX", key, 20*60, json_response)

			if err != nil {
				log.Println(err)
			}

			city_weather <- *weather
		}

	}()

	return city_weather
}
<|endoftext|>


<commit_before>package network

import (
	"fmt"
	"net"
	"reflect"
	"sort"
	"testing"

	"github.com/quilt/quilt/db"
	"github.com/quilt/quilt/join"
	"github.com/quilt/quilt/minion/ipdef"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestAllocateContainerIPs(t *testing.T) {
	conn := db.New()

	conn.Txn(db.AllTables...).Run(func(view db.Database) error {
		dbc := view.InsertContainer()
		dbc.IP = "10.0.0.2"
		dbc.StitchID = "1"
		view.Commit(dbc)

		dbc = view.InsertContainer()
		dbc.StitchID = "2"
		view.Commit(dbc)

		allocateContainerIPs(view, map[string]struct{}{})
		return nil
	})

	dbcs := conn.SelectFromContainer(nil)
	assert.Len(t, dbcs, 2)

	sort.Sort(db.ContainerSlice(dbcs))

	dbc := dbcs[0]
	dbc.ID = 0
	assert.Equal(t, db.Container{IP: "10.0.0.2", StitchID: "1"}, dbc)

	dbc = dbcs[1]
	assert.Equal(t, "2", dbc.StitchID)
	assert.True(t, ipdef.QuiltSubnet.Contains(net.ParseIP(dbc.IP)))
}

func TestUpdateLabelIPs(t *testing.T) {
	conn := db.New()

	conn.Txn(db.AllTables...).Run(func(view db.Database) error {
		dbc := view.InsertContainer()
		dbc.Labels = []string{"red", "blue"}
		dbc.StitchID = "1"
		dbc.IP = "1.1.1.1"
		view.Commit(dbc)

		dbc = view.InsertContainer()
		dbc.Labels = []string{"red"}
		dbc.StitchID = "2"
		dbc.IP = "2.2.2.2"
		view.Commit(dbc)

		label := view.InsertLabel()
		label.Label = "yellow"
		view.Commit(label)

		return nil
	})

	conn.Txn(db.AllTables...).Run(func(view db.Database) error {
		assert.NoError(t, updateLabelIPs(view, map[string]struct{}{}))
		return nil
	})

	exp := []db.Label{
		{
			Label:        "blue",
			ContainerIPs: []string{"1.1.1.1"},
		}, {
			Label:        "red",
			ContainerIPs: []string{"1.1.1.1", "2.2.2.2"},
		},
	}

	// Ensure that the label name and container IPs match, and that the generated
	// IP is within the Quilt subnet.
	key := func(expIntf interface{}, actualIntf interface{}) int {
		exp := expIntf.(db.Label)
		actual := actualIntf.(db.Label)

		if exp.Label == actual.Label &&
			reflect.DeepEqual(exp.ContainerIPs, actual.ContainerIPs) &&
			ipdef.QuiltSubnet.Contains(net.ParseIP(actual.IP)) {
			return 0
		}
		return -1
	}

	_, extraExp, extraActual := join.Join(exp, conn.SelectFromLabel(nil), key)
	assert.Len(t, extraExp, 0)
	assert.Len(t, extraActual, 0)
}

func TestAllocate(t *testing.T) {
	subnet := net.IPNet{
		IP:   net.IPv4(0xab, 0xcd, 0xe0, 0x00),
		Mask: net.CIDRMask(20, 32),
	}
	conflicts := map[string]struct{}{}
	ipSet := map[string]struct{}{}

	// Only 4k IPs, in 0xfffff000. Guaranteed a collision
	for i := 0; i < 5000; i++ {
		ip, err := allocateIP(ipSet, subnet)
		if err != nil {
			continue
		}

		if _, ok := conflicts[ip]; ok {
			t.Fatalf("IP Double allocation: 0x%x", ip)
		}

		require.True(t, subnet.Contains(net.ParseIP(ip)),
			fmt.Sprintf("\"%s\" is not in %s", ip, subnet))
		conflicts[ip] = struct{}{}
	}

	assert.Equal(t, len(conflicts), len(ipSet))
	if len(conflicts) < 2500 || len(conflicts) > 4096 {
		// If the code's working, this is possible but *extremely* unlikely.
		// Probably a bug.
		t.Errorf("Too few conflicts: %d", len(conflicts))
	}
}
<commit_msg>ip: Run unit tests in parallel<commit_after>package network

import (
	"fmt"
	"net"
	"reflect"
	"sort"
	"testing"

	"github.com/quilt/quilt/db"
	"github.com/quilt/quilt/join"
	"github.com/quilt/quilt/minion/ipdef"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestAllocateContainerIPs(t *testing.T) {
	t.Parallel()
	conn := db.New()

	conn.Txn(db.AllTables...).Run(func(view db.Database) error {
		dbc := view.InsertContainer()
		dbc.IP = "10.0.0.2"
		dbc.StitchID = "1"
		view.Commit(dbc)

		dbc = view.InsertContainer()
		dbc.StitchID = "2"
		view.Commit(dbc)

		allocateContainerIPs(view, map[string]struct{}{})
		return nil
	})

	dbcs := conn.SelectFromContainer(nil)
	assert.Len(t, dbcs, 2)

	sort.Sort(db.ContainerSlice(dbcs))

	dbc := dbcs[0]
	dbc.ID = 0
	assert.Equal(t, db.Container{IP: "10.0.0.2", StitchID: "1"}, dbc)

	dbc = dbcs[1]
	assert.Equal(t, "2", dbc.StitchID)
	assert.True(t, ipdef.QuiltSubnet.Contains(net.ParseIP(dbc.IP)))
}

func TestUpdateLabelIPs(t *testing.T) {
	t.Parallel()
	conn := db.New()

	conn.Txn(db.AllTables...).Run(func(view db.Database) error {
		dbc := view.InsertContainer()
		dbc.Labels = []string{"red", "blue"}
		dbc.StitchID = "1"
		dbc.IP = "1.1.1.1"
		view.Commit(dbc)

		dbc = view.InsertContainer()
		dbc.Labels = []string{"red"}
		dbc.StitchID = "2"
		dbc.IP = "2.2.2.2"
		view.Commit(dbc)

		label := view.InsertLabel()
		label.Label = "yellow"
		view.Commit(label)

		return nil
	})

	conn.Txn(db.AllTables...).Run(func(view db.Database) error {
		assert.NoError(t, updateLabelIPs(view, map[string]struct{}{}))
		return nil
	})

	exp := []db.Label{
		{
			Label:        "blue",
			ContainerIPs: []string{"1.1.1.1"},
		}, {
			Label:        "red",
			ContainerIPs: []string{"1.1.1.1", "2.2.2.2"},
		},
	}

	// Ensure that the label name and container IPs match, and that the generated
	// IP is within the Quilt subnet.
	key := func(expIntf interface{}, actualIntf interface{}) int {
		exp := expIntf.(db.Label)
		actual := actualIntf.(db.Label)

		if exp.Label == actual.Label &&
			reflect.DeepEqual(exp.ContainerIPs, actual.ContainerIPs) &&
			ipdef.QuiltSubnet.Contains(net.ParseIP(actual.IP)) {
			return 0
		}
		return -1
	}

	_, extraExp, extraActual := join.Join(exp, conn.SelectFromLabel(nil), key)
	assert.Len(t, extraExp, 0)
	assert.Len(t, extraActual, 0)
}

func TestAllocate(t *testing.T) {
	t.Parallel()

	subnet := net.IPNet{
		IP:   net.IPv4(0xab, 0xcd, 0xe0, 0x00),
		Mask: net.CIDRMask(20, 32),
	}
	conflicts := map[string]struct{}{}
	ipSet := map[string]struct{}{}

	// Only 4k IPs, in 0xfffff000. Guaranteed a collision
	for i := 0; i < 5000; i++ {
		ip, err := allocateIP(ipSet, subnet)
		if err != nil {
			continue
		}

		if _, ok := conflicts[ip]; ok {
			t.Fatalf("IP Double allocation: 0x%x", ip)
		}

		require.True(t, subnet.Contains(net.ParseIP(ip)),
			fmt.Sprintf("\"%s\" is not in %s", ip, subnet))
		conflicts[ip] = struct{}{}
	}

	assert.Equal(t, len(conflicts), len(ipSet))
	if len(conflicts) < 2500 || len(conflicts) > 4096 {
		// If the code's working, this is possible but *extremely* unlikely.
		// Probably a bug.
		t.Errorf("Too few conflicts: %d", len(conflicts))
	}
}
<|endoftext|>


<commit_before>package server

import (
	"github.com/centurylinkcloud/clc-go-cli/models"
	"github.com/centurylinkcloud/clc-go-cli/models/alert"
	"github.com/centurylinkcloud/clc-go-cli/models/customfields"
)

type Disk struct {
	Id             string
	SizeGB         float64
	PartitionPaths []string
}

type Partition struct {
	SizeGB float64
	Path   string
}

type AddDiskRequest struct {
	Path   string
	SizeGB int64
	Type   string
}

type KeepDiskRequest struct {
	DiskId string
	SizeGB int64
}

type PackageDef struct {
	PackageId  string
	Parameters map[string]string
}

type Details struct {
	IpAddresses       []IPAddresses
	AlertPolicies     []alert.AlertPolicy
	Cpu               int64
	DiskCount         int64
	HostName          string
	InMaintenanceMode bool
	MemoryMB          int64
	PowerState        string
	StorageGB         int64
	Disks             []Disk
	Partitions        []Partition
	Snapshots         []Snapshot
	CustomFields      []customfields.FullDef
}

type IPAddresses struct {
	Public   string
	Internal string
}

type Snapshot struct {
	Name  string
	Links []models.LinkEntity
}
<commit_msg>#48 - Extract snapshot IDs from the server links & include them in the output<commit_after>package server

import (
	"encoding/json"
	"strings"

	"github.com/centurylinkcloud/clc-go-cli/models"
	"github.com/centurylinkcloud/clc-go-cli/models/alert"
	"github.com/centurylinkcloud/clc-go-cli/models/customfields"
)

type Disk struct {
	Id             string
	SizeGB         float64
	PartitionPaths []string
}

type Partition struct {
	SizeGB float64
	Path   string
}

type AddDiskRequest struct {
	Path   string
	SizeGB int64
	Type   string
}

type KeepDiskRequest struct {
	DiskId string
	SizeGB int64
}

type PackageDef struct {
	PackageId  string
	Parameters map[string]string
}

type Details struct {
	IpAddresses       []IPAddresses
	AlertPolicies     []alert.AlertPolicy
	Cpu               int64
	DiskCount         int64
	HostName          string
	InMaintenanceMode bool
	MemoryMB          int64
	PowerState        string
	StorageGB         int64
	Disks             []Disk
	Partitions        []Partition
	Snapshots         []Snapshot
	CustomFields      []customfields.FullDef
}

type IPAddresses struct {
	Public   string
	Internal string
}

type Snapshot struct {
	Name  string
	Id    string
	Links []models.LinkEntity
}

func (s *Snapshot) UnmarshalJSON(data []byte) error {
	// Here we are getting the snapshot ID out of the server links. Looks
	// rather hacky but there doesn't seem to be another way for retrieving it.
	id := func() string {
		m := struct {
			Links []struct {
				Rel  string
				Href string
			}
		}{}
		if err := json.Unmarshal(data, &m); err != nil {
			return ""
		}
		for _, link := range m.Links {
			if link.Rel != "self" {
				continue
			}
			tokens := strings.Split(link.Href, "/")
			return tokens[len(tokens)-1]
		}
		return ""
	}()

	if id != "" {
		s.Id = id
	}

	type SimpleSnapshot Snapshot
	return json.Unmarshal(data, &struct {
		*SimpleSnapshot
	}{
		SimpleSnapshot: (*SimpleSnapshot)(s),
	})
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net"
	"time"

	fastping "github.com/tatsushid/go-fastping"
)

type PingCheck struct {
	Host string
}

func ParsePingCheck(data map[string]interface{}) PingCheck {
	check := PingCheck{}

	if data["host"] != nil {
		check.Host = data["host"].(string)
	}

	return check
}

func (check PingCheck) Name() string {
	return "PING"
}

func (check PingCheck) Perform() error {
	log.Printf("Performing PING check for ip=%v\n", check.Host)
	if check.Host == "" {
		return fmt.Errorf("Host should not be empty")
	}

	pongCount := 0

	p := fastping.NewPinger()
	p.Network("udp")

	ra, err := net.ResolveIPAddr("ip4:icmp", check.Host)
	if err != nil {
		return err
	}
	p.AddIPAddr(ra)

	p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
		pongCount += 1
	}

	err = p.Run()
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Replace fastping with os.exec call of ping<commit_after>package main

import (
	"fmt"
	"log"
	"os/exec"
)

type PingCheck struct {
	Host string
}

func ParsePingCheck(data map[string]interface{}) PingCheck {
	check := PingCheck{}

	if data["host"] != nil {
		check.Host = data["host"].(string)
	}

	return check
}

func (check PingCheck) Name() string {
	return "PING"
}

func (check PingCheck) Perform() error {
	log.Printf("Performing %v check for ip=%v\n", check.Name(), check.Host)
	if check.Host == "" {
		return fmt.Errorf("Host should not be empty")
	}

	return exec.Command("ping", "-c", "1", check.Host).Run()
}
<|endoftext|>


<commit_before>package ca

import (
	"crypto"
	"crypto/rand"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/json"
	"errors"
	"fmt"
	"math/big"
	"time"

	"github.com/cloudflare/cfssl/config"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/signer"
	"github.com/cloudflare/cfssl/signer/local"
)

type KeyProvider interface {
	GenerateKeyPair(label string, algo string, size int) (crypto.Signer, error)
	FindKeyPair(key crypto.PublicKey) (crypto.Signer, error)
}

// CertificationAuthority represents a certification authority.
type CertificationAuthority struct {
	db *database

	cert   *x509.Certificate
	signer signer.Signer
}

// Init creates a CA with given config.
func Init(cfg *Config, kp KeyProvider) (*CertificationAuthority, error) {
	req := cfg.CertificateRequest()
	key, err := kp.GenerateKeyPair(req.CN, req.KeyRequest.Algo(), req.KeyRequest.Size())
	if err != nil {
		return nil, err
	}

	db, err := openDB(cfg.CAFile)
	if err != nil {
		return nil, err
	}

	csrPEM, err := csr.Generate(key, req)
	if err != nil {
		return nil, err
	}
	err = db.SetMetadata([]byte("csr"), csrPEM)
	if err != nil {
		return nil, err
	}

	policy, err := cfg.Signing()
	if err != nil {
		return nil, err
	}

	ca, err := newCA(key, nil, policy, db)
	if err != nil {
		return nil, err
	}

	if cfg.SelfSign {
		certPEM, err := ca.Issue(csrPEM)
		if err != nil {
			return nil, err
		}
		err = db.SetMetadata([]byte("cert"), certPEM)
		if err != nil {
			return nil, err
		}

		ca.cert, err = helpers.ParseCertificatePEM(certPEM)
		if err != nil {
			return nil, err
		}
	}

	return ca, nil
}

// Open opens an existing CA.
func Open(caFile string, kp KeyProvider) (*CertificationAuthority, error) {
	db, err := openDB(caFile)
	if err != nil {
		return nil, err
	}

	certPEM, err := db.GetMetadata([]byte("cert"))
	if err != nil {
		return nil, err
	}
	cert, err := helpers.ParseCertificatePEM(certPEM)
	if err != nil {
		return nil, err
	}

	key, err := kp.FindKeyPair(cert.PublicKey)
	if err != nil {
		return nil, err
	}

	policyJSON, err := db.GetMetadata([]byte("policy"))
	if err != nil {
		return nil, err
	}
	var policy *config.Signing
	err = json.Unmarshal(policyJSON, policy)
	if err != nil {
		return nil, err
	}

	return newCA(key, cert, policy, db)
}

// newCA returns a new CA. If the CA does not have a certificate yet,
// set cert to nil.
func newCA(key crypto.Signer, cert *x509.Certificate, policy *config.Signing, db *database) (*CertificationAuthority, error) {
	signer, err := local.NewSigner(key, cert, signer.DefaultSigAlgo(key), policy)
	if err != nil {
		return nil, fmt.Errorf("failed to create signer: %s", err)
	}
	signer.SetDBAccessor(db.Accessor())

	return &CertificationAuthority{db, cert, signer}, nil
}

// Certificate returns the certificate of the CA.
func (ca *CertificationAuthority) Certificate() (*x509.Certificate, error) {
	if ca.cert == nil {
		return nil, errors.New("ca cert unavailable")
	}

	return ca.cert, nil
}

// Certificate returns the certificate of the CA in PEM encoding.
func (ca *CertificationAuthority) CertificatePEM() ([]byte, error) {
	return ca.db.GetMetadata([]byte("cert"))
}

// CertificateRequest returns the certificate signing request of the CA.
func (ca *CertificationAuthority) CertificateRequest() (*x509.CertificateRequest, error) {
	csrPEM, err := ca.CertificateRequestPEM()
	if err != nil {
		return nil, err
	}

	return helpers.ParseCSRPEM(csrPEM)
}

// CertificateRequestPEM returns the certificate signing request of the
// CA in PEM encoding.
func (ca *CertificationAuthority) CertificateRequestPEM() ([]byte, error) {
	return ca.db.GetMetadata([]byte("csr"))
}

// KeyID returns the identifier of the signing key, which will also be
// the Authority Key Identifier (AKI) for issued certificates.
func (ca *CertificationAuthority) KeyID() []byte {
	return ca.cert.SubjectKeyId
}

// Issue signs a PEM-encoded CSR and returns the certificate in PEM.
func (ca *CertificationAuthority) Issue(csrPEM []byte) ([]byte, error) {
	var oidExtensionAuthorityKeyId = config.OID([]int{2, 5, 29, 35})

	req := signer.SignRequest{
		Request: string(csrPEM),
		Extensions: []signer.Extension{
			signer.Extension{
				ID:       oidExtensionAuthorityKeyId,
				Critical: false,
				Value:    string(ca.KeyID()),
			},
		},
	}

	return ca.signer.Sign(req)
}

// Revoke marks the certificate identified by its serial number and
// authority key identifier revoked. The reasonCode is defined in
// RFC 5280 5.3.1.
func (ca *CertificationAuthority) Revoke(serial, aki string, reasonCode int) error {
	return ca.db.Accessor().RevokeCertificate(serial, aki, reasonCode)
}

// CRL returns a DER-encoded Certificate Revocation List, signed by the CA.
func (ca *CertificationAuthority) CRL(ttl time.Duration) ([]byte, error) {
	if ca.cert == nil {
		return nil, errors.New("nil ca certificate")
	}

	certs, err := ca.db.Accessor().GetRevokedAndUnexpiredCertificates()
	if err != nil {
		return nil, err
	}

	var revokedCerts []pkix.RevokedCertificate
	for _, certRecord := range certs {
		serialInt := new(big.Int)
		serialInt.SetString(certRecord.Serial, 10)

		revokedCert := pkix.RevokedCertificate{
			SerialNumber:   serialInt,
			RevocationTime: certRecord.RevokedAt,
		}
		revokedCerts = append(revokedCerts, revokedCert)
	}

	return ca.cert.CreateCRL(rand.Reader, ca.signer, revokedCerts, time.Now(), time.Now().Add(ttl))
}
<commit_msg>Allow CA certificate to be imported from outside<commit_after>package ca

import (
	"crypto"
	"crypto/rand"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/json"
	"errors"
	"fmt"
	"math/big"
	"time"

	"github.com/cloudflare/cfssl/config"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/helpers"
	"github.com/cloudflare/cfssl/signer"
	"github.com/cloudflare/cfssl/signer/local"
)

type KeyProvider interface {
	GenerateKeyPair(label string, algo string, size int) (crypto.Signer, error)
	FindKeyPair(key crypto.PublicKey) (crypto.Signer, error)
}

// CertificationAuthority represents a certification authority.
type CertificationAuthority struct {
	db *database

	cert   *x509.Certificate
	signer signer.Signer
}

// Init creates a CA with given config.
func Init(cfg *Config, kp KeyProvider) (*CertificationAuthority, error) {
	req := cfg.CertificateRequest()
	key, err := kp.GenerateKeyPair(req.CN, req.KeyRequest.Algo(), req.KeyRequest.Size())
	if err != nil {
		return nil, err
	}

	db, err := openDB(cfg.CAFile)
	if err != nil {
		return nil, err
	}

	csrPEM, err := csr.Generate(key, req)
	if err != nil {
		return nil, err
	}
	err = db.SetMetadata([]byte("csr"), csrPEM)
	if err != nil {
		return nil, err
	}

	policy, err := cfg.Signing()
	if err != nil {
		return nil, err
	}

	ca, err := newCA(key, nil, policy, db)
	if err != nil {
		return nil, err
	}

	if cfg.SelfSign {
		certPEM, err := ca.Issue(csrPEM)
		if err != nil {
			return nil, err
		}

		err = ca.ImportCertificate(certPEM)
		if err != nil {
			return nil, err
		}
	}

	return ca, nil
}

// Open opens an existing CA.
func Open(caFile string, kp KeyProvider) (*CertificationAuthority, error) {
	db, err := openDB(caFile)
	if err != nil {
		return nil, err
	}

	certPEM, err := db.GetMetadata([]byte("cert"))
	if err != nil {
		return nil, err
	}
	cert, err := helpers.ParseCertificatePEM(certPEM)
	if err != nil {
		return nil, err
	}

	key, err := kp.FindKeyPair(cert.PublicKey)
	if err != nil {
		return nil, err
	}

	policyJSON, err := db.GetMetadata([]byte("policy"))
	if err != nil {
		return nil, err
	}
	var policy *config.Signing
	err = json.Unmarshal(policyJSON, policy)
	if err != nil {
		return nil, err
	}

	return newCA(key, cert, policy, db)
}

// newCA returns a new CA. If the CA does not have a certificate yet,
// set cert to nil.
func newCA(key crypto.Signer, cert *x509.Certificate, policy *config.Signing, db *database) (*CertificationAuthority, error) {
	signer, err := local.NewSigner(key, cert, signer.DefaultSigAlgo(key), policy)
	if err != nil {
		return nil, fmt.Errorf("failed to create signer: %s", err)
	}
	signer.SetDBAccessor(db.Accessor())

	return &CertificationAuthority{db, cert, signer}, nil
}

// Certificate returns the certificate of the CA.
func (ca *CertificationAuthority) Certificate() (*x509.Certificate, error) {
	if ca.cert == nil {
		return nil, errors.New("ca cert unavailable")
	}

	return ca.cert, nil
}

// Certificate returns the certificate of the CA in PEM encoding.
func (ca *CertificationAuthority) CertificatePEM() ([]byte, error) {
	return ca.db.GetMetadata([]byte("cert"))
}

// ImportCertificate imports the given certificate if the CA does not
// have one.
func (ca *CertificationAuthority) ImportCertificate(certPEM []byte) error {
	if ca.cert != nil {
		return errors.New("ca cert exists")
	}

	cert, err := helpers.ParseCertificatePEM(certPEM)
	if err != nil {
		return err
	}

	// TODO: Check signature and compare with original CSR.

	err = ca.db.SetMetadata([]byte("cert"), certPEM)
	if err != nil {
		return err
	}

	ca.cert = cert
	return nil
}

// CertificateRequest returns the certificate signing request of the CA.
func (ca *CertificationAuthority) CertificateRequest() (*x509.CertificateRequest, error) {
	csrPEM, err := ca.CertificateRequestPEM()
	if err != nil {
		return nil, err
	}

	return helpers.ParseCSRPEM(csrPEM)
}

// CertificateRequestPEM returns the certificate signing request of the
// CA in PEM encoding.
func (ca *CertificationAuthority) CertificateRequestPEM() ([]byte, error) {
	return ca.db.GetMetadata([]byte("csr"))
}

// KeyID returns the identifier of the signing key, which will also be
// the Authority Key Identifier (AKI) for issued certificates.
func (ca *CertificationAuthority) KeyID() []byte {
	return ca.cert.SubjectKeyId
}

// Issue signs a PEM-encoded CSR and returns the certificate in PEM.
func (ca *CertificationAuthority) Issue(csrPEM []byte) ([]byte, error) {
	var oidExtensionAuthorityKeyId = config.OID([]int{2, 5, 29, 35})

	req := signer.SignRequest{
		Request: string(csrPEM),
		Extensions: []signer.Extension{
			signer.Extension{
				ID:       oidExtensionAuthorityKeyId,
				Critical: false,
				Value:    string(ca.KeyID()),
			},
		},
	}

	return ca.signer.Sign(req)
}

// Revoke marks the certificate identified by its serial number and
// authority key identifier revoked. The reasonCode is defined in
// RFC 5280 5.3.1.
func (ca *CertificationAuthority) Revoke(serial, aki string, reasonCode int) error {
	return ca.db.Accessor().RevokeCertificate(serial, aki, reasonCode)
}

// CRL returns a DER-encoded Certificate Revocation List, signed by the CA.
func (ca *CertificationAuthority) CRL(ttl time.Duration) ([]byte, error) {
	if ca.cert == nil {
		return nil, errors.New("nil ca certificate")
	}

	certs, err := ca.db.Accessor().GetRevokedAndUnexpiredCertificates()
	if err != nil {
		return nil, err
	}

	var revokedCerts []pkix.RevokedCertificate
	for _, certRecord := range certs {
		serialInt := new(big.Int)
		serialInt.SetString(certRecord.Serial, 10)

		revokedCert := pkix.RevokedCertificate{
			SerialNumber:   serialInt,
			RevocationTime: certRecord.RevokedAt,
		}
		revokedCerts = append(revokedCerts, revokedCert)
	}

	return ca.cert.CreateCRL(rand.Reader, ca.signer, revokedCerts, time.Now(), time.Now().Add(ttl))
}
<|endoftext|>


<commit_before>/*
Package db contains functions related to database.
 * db.go includes conneting to db, query and insertion.
 * dbschema.go contains definitions of struct for db tables.
   Currently it only contains Module struct.
*/
package db

import (
	"database/sql"
	"fmt"
	"os"
	"strconv"

	// Go postgres driver for Go's database/sql package
	"github.com/golang/glog"
	_ "github.com/lib/pq"
)

// SQL stataments used in this package.
// Query statements can be appended based on its query parameters.
const (
	insertModule  = `INSERT INTO modules (orgName, name, version, data) VALUES($1, $2, $3, $4)`
	selectModules = `select * from modules`
)

var db *sql.DB

// Establish connection to database, *db* variable is assigned when opening database.
// This should only be called once before any other database function is called.
//
// Users need set environment variables for connection, including
//  * DB_HOST:          host address of target db instances, by default: localhost.
//  * DB_PORT:          port number of postgres db, by default: 5432.
//  * DB_USERNAME:      username of database, error would be returned if not set.
//  * DB_PWD:           password of target database, error would be returned if not set.
//  * DB_NAME:          name of database for connection, error would be returned if not set.
//  * DB_SOCKER_DIR:    directory of Unix socket in Cloud Run which serves as Cloud SQL
//                      Auth proxy to connect to postgres database.
//                      If service is deployed on Cloud Run, just use the default value.
//                      By default, it is set to `/cloudsql`.
func ConnectDB() error {
	var port int         // port number of target database
	var user string      // username of target database
	var password string  // password of target database
	var dbname string    // name of target database
	var host string      // host address of target database
	var socketDir string // (Cloud Run only) Directory of Unix socket
	var psqlconn string  // connection string used to connect to traget database

	// read db config from env

	port = 5432
	if portStr, ok := os.LookupEnv("DB_PORT"); !ok {
		glog.Infof("DB_PORT not set, setting port to %d", port)
	} else {
		var err error
		if port, err = strconv.Atoi(portStr); err != nil {
			return fmt.Errorf("DB_PORT in incorrect format: %v", err)
		}
	}

	user, ok := os.LookupEnv("DB_USERNAME")
	if !ok {
		return fmt.Errorf("DB_USERNAME not set")
	}

	if password, ok = os.LookupEnv("DB_PWD"); !ok {
		return fmt.Errorf("DB_PWD not set")
	}

	if dbname, ok = os.LookupEnv("DB_NAME"); !ok {
		return fmt.Errorf("DB_NAME not set")
	}

	if socketDir, ok = os.LookupEnv("DB_SOCKET_DIR"); !ok {
		socketDir = "/cloudsql"
	}

	host, ok = os.LookupEnv("DB_HOST")
	switch {
	case !ok:
		glog.Infoln("DB_HOST not set, setting host to localhost")
		host = "localhost"
		fallthrough
	case host == "localhost":
		// This connection string is used if service is not deployed on Cloud Run,
		// instead connection is made from localhost via Cloud SQL proxy.
		psqlconn = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
	default:
		psqlconn = fmt.Sprintf("host=%s/%s port=%d user=%s password=%s dbname=%s", socketDir, host, port, user, password, dbname)
	}

	// open database
	var err error
	db, err = sql.Open("postgres", psqlconn)
	if err != nil {
		return fmt.Errorf("open database failed: %v", err)
	}

	// see if connection is established successfully
	if err := db.Ping(); err != nil {
		return fmt.Errorf("ping database failed: %v", err)
	}

	return nil
}

// Insert module into database given values of four field of MODULE schema.
// Error is returned when insertion failed.
func InsertModule(orgName string, name string, version string, data string) error {
	if _, err := db.Exec(insertModule, orgName, name, version, data); err != nil {
		return fmt.Errorf("insert module into db failed: %v", err)
	}
	return nil
}

// Scan from queried modules from rows one by one, rows are *not* closed inside.
// Return slice of db Module struct each field of which corresponds to one column in db.
// Error is returned when scan rows failed.
func ReadModluesByRow(rows *sql.Rows) ([]Module, error) {
	var modules []Module
	for rows.Next() {
		var module Module
		if err := rows.Scan(&module.OrgName, &module.Name, &module.Version, &module.Data); err != nil {
			return nil, fmt.Errorf("scan db rows failure, %v", err)
		}
		modules = append(modules, module)
	}
	return modules, nil
}

// This function is used to generate query statement string based on query parameters.
// * parmNames is a list of names of all non-nil query parameters.
// * baseQuery is query statement without any query parameters.
func FormatQueryStr(parmNames []string, baseQuery string) string {
	queryStmt := baseQuery
	for i := 0; i < len(parmNames); i++ {
		if i == 0 {
			queryStmt += " where"
		} else {
			queryStmt += " and"
		}
		queryStmt += fmt.Sprintf(" %s=$%d", parmNames[i], i+1)
	}
	return queryStmt
}

// Query modules of organization with *orgName* from database.
// If orgName is null then directly query all modules.
// Return slice of db Module struct each field of which corresponds to one column in db.
// Error is returned when query or reading data failed.
func QueryModulesByOrgName(orgName *string) ([]Module, error) {
	parms := []interface{}{} // parms is used to store value of non-nil query parameters
	parmNames := []string{}  // parmNames is used to store name of non-nil query parameters

	if orgName != nil {
		parms = append(parms, *orgName)
		parmNames = append(parmNames, "orgName")
	}

	// Format query statement string based on non-nil query parameters
	queryStmt := FormatQueryStr(parmNames, selectModules)

	rows, err := db.Query(queryStmt, parms...)
	if err != nil {
		return nil, fmt.Errorf("QueryModulesByOrgName failed: %v", err)
	}

	defer rows.Close()

	return ReadModluesByRow(rows)
}

// Query modules by its key (name, version), it is possible that parameters are null.
// If both parameters are null, this equals query for all modules.
// Return slice of db Module struct each field of which corresponds to one column in db.
// Error is returned when query or reading data failed.
func QueryModulesByKey(name *string, version *string) ([]Module, error) {
	parms := []interface{}{} // parms is used to store value of non-nil query parameters
	parmNames := []string{}  // parmNames is used to store name of non-nil query parameters

	if name != nil {
		parms = append(parms, *name)
		parmNames = append(parmNames, "name")
	}

	if version != nil {
		parms = append(parms, *version)
		parmNames = append(parmNames, "version")
	}

	// Format query statement string based on non-nil query parameters
	queryStmt := FormatQueryStr(parmNames, selectModules)

	rows, err := db.Query(queryStmt, parms...)
	if err != nil {
		return nil, fmt.Errorf("QueryModulesByOrgName failed: %v", err)
	}

	defer rows.Close()

	return ReadModluesByRow(rows)
}

// Close db connection
func Close() error {
	return db.Close()
}
<commit_msg>Fix some nits on style<commit_after>/*
Package db contains functions related to database.
 * db.go includes conneting to db, query and insertion.
 * dbschema.go contains definitions of struct for db tables.
   Currently it only contains Module struct.
*/
package db

import (
	"database/sql"
	"fmt"
	"os"
	"strconv"

	"github.com/golang/glog"

	// Go postgres driver for Go's database/sql package
	_ "github.com/lib/pq"
)

// SQL stataments used in this package.
// Query statements can be appended based on its query parameters.
const (
	insertModule  = `INSERT INTO modules (orgName, name, version, data) VALUES($1, $2, $3, $4)`
	selectModules = `select * from modules`
)

var db *sql.DB

// Establish connection to database, *db* variable is assigned when opening database.
// This should only be called once before any other database function is called.
//
// Users need set environment variables for connection, including
//  * DB_HOST:          host address of target db instances, by default: localhost.
//  * DB_PORT:          port number of postgres db, by default: 5432.
//  * DB_USERNAME:      username of database, error would be returned if not set.
//  * DB_PWD:           password of target database, error would be returned if not set.
//  * DB_NAME:          name of database for connection, error would be returned if not set.
//  * DB_SOCKER_DIR:    directory of Unix socket in Cloud Run which serves as Cloud SQL
//                      Auth proxy to connect to postgres database.
//                      If service is deployed on Cloud Run, just use the default value.
//                      By default, it is set to `/cloudsql`.
func ConnectDB() error {
	// read db config from env

	// port number of target database
	port := 5432
	if portStr, ok := os.LookupEnv("DB_PORT"); !ok {
		glog.Infof("DB_PORT not set, setting port to %d", port)
	} else {
		var err error
		if port, err = strconv.Atoi(portStr); err != nil {
			return fmt.Errorf("DB_PORT in incorrect format: %v", err)
		}
	}

	// username of target database
	user, ok := os.LookupEnv("DB_USERNAME")
	if !ok {
		return fmt.Errorf("DB_USERNAME not set")
	}

	// password of target database
	password, ok := os.LookupEnv("DB_PWD")
	if !ok {
		return fmt.Errorf("DB_PWD not set")
	}

	// name of target database
	dbname, ok := os.LookupEnv("DB_NAME")
	if !ok {
		return fmt.Errorf("DB_NAME not set")
	}

	// (Cloud Run only) Directory of Unix socket
	socketDir, ok := os.LookupEnv("DB_SOCKET_DIR")
	if !ok {
		socketDir = "/cloudsql"
	}

	var psqlconn string // connection string used to connect to traget database

	// host address of target database
	host, ok := os.LookupEnv("DB_HOST")
	switch {
	case !ok:
		glog.Infoln("DB_HOST not set, setting host to localhost")
		host = "localhost"
		fallthrough
	case host == "localhost":
		// This connection string is used if service is not deployed on Cloud Run,
		// instead connection is made from localhost via Cloud SQL proxy.
		psqlconn = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", host, port, user, password, dbname)
	default:
		psqlconn = fmt.Sprintf("host=%s/%s port=%d user=%s password=%s dbname=%s", socketDir, host, port, user, password, dbname)
	}

	// open database
	var err error
	db, err = sql.Open("postgres", psqlconn)
	if err != nil {
		return fmt.Errorf("open database failed: %v", err)
	}

	// see if connection is established successfully
	if err := db.Ping(); err != nil {
		return fmt.Errorf("ping database failed: %v", err)
	}

	return nil
}

// Close db connection
func Close() error {
	return db.Close()
}

// Insert module into database given values of four field of MODULE schema.
// Error is returned when insertion failed.
func InsertModule(orgName string, name string, version string, data string) error {
	if _, err := db.Exec(insertModule, orgName, name, version, data); err != nil {
		return fmt.Errorf("insert module into db failed: %v", err)
	}
	return nil
}

// Scan from queried modules from rows one by one, rows are *not* closed inside.
// Return slice of db Module struct each field of which corresponds to one column in db.
// Error is returned when scan rows failed.
func ReadModulesByRow(rows *sql.Rows) ([]Module, error) {
	var modules []Module
	for rows.Next() {
		var module Module
		if err := rows.Scan(&module.OrgName, &module.Name, &module.Version, &module.Data); err != nil {
			return nil, fmt.Errorf("scan db rows failure, %v", err)
		}
		modules = append(modules, module)
	}
	return modules, nil
}

// This function is used to generate query statement string based on query parameters.
// * parmNames is a list of names of all non-nil query parameters.
// * baseQuery is query statement without any query parameters.
func FormatQueryStr(parmNames []string, baseQuery string) string {
	queryStmt := baseQuery
	for i := 0; i < len(parmNames); i++ {
		if i == 0 {
			queryStmt += " where"
		} else {
			queryStmt += " and"
		}
		queryStmt += fmt.Sprintf(" %s=$%d", parmNames[i], i+1)
	}
	return queryStmt
}

// Query modules of organization with *orgName* from database.
// If orgName is null then directly query all modules.
// Return slice of db Module struct each field of which corresponds to one column in db.
// Error is returned when query or reading data failed.
func QueryModulesByOrgName(orgName *string) ([]Module, error) {
	parms := []interface{}{} // parms is used to store value of non-nil query parameters
	parmNames := []string{}  // parmNames is used to store name of non-nil query parameters

	if orgName != nil {
		parms = append(parms, *orgName)
		parmNames = append(parmNames, "orgName")
	}

	// Format query statement string based on non-nil query parameters
	queryStmt := FormatQueryStr(parmNames, selectModules)

	rows, err := db.Query(queryStmt, parms...)
	if err != nil {
		return nil, fmt.Errorf("QueryModulesByOrgName failed: %v", err)
	}

	defer rows.Close()

	return ReadModulesByRow(rows)
}

// Query modules by its key (name, version), it is possible that parameters are null.
// If both parameters are null, this equals query for all modules.
// Return slice of db Module struct each field of which corresponds to one column in db.
// Error is returned when query or reading data failed.
func QueryModulesByKey(name *string, version *string) ([]Module, error) {
	parms := []interface{}{} // parms is used to store value of non-nil query parameters
	parmNames := []string{}  // parmNames is used to store name of non-nil query parameters

	if name != nil {
		parms = append(parms, *name)
		parmNames = append(parmNames, "name")
	}

	if version != nil {
		parms = append(parms, *version)
		parmNames = append(parmNames, "version")
	}

	// Format query statement string based on non-nil query parameters
	queryStmt := FormatQueryStr(parmNames, selectModules)

	rows, err := db.Query(queryStmt, parms...)
	if err != nil {
		return nil, fmt.Errorf("QueryModulesByOrgName failed: %v", err)
	}

	defer rows.Close()

	return ReadModulesByRow(rows)
}
<|endoftext|>


<commit_before>package mux

import "net/http"

// MiddlewareFunc is a function which receives an http.Handler and returns another http.Handler.
// Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed
// to it, and then calls the handler passed as parameter to the MiddlewareFunc.
type MiddlewareFunc func(http.Handler) http.Handler

// middleware interface is anything which implements a MiddlewareFunc named Middleware.
type middleware interface {
	Middleware(handler http.Handler) http.Handler
}

// MiddlewareFunc also implements the middleware interface.
func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler {
	return mw(handler)
}

// Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
func (r *Router) Use(mwf MiddlewareFunc) {
	r.middlewares = append(r.middlewares, mwf)
}

// useInterface appends a middleware to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
func (r *Router) useInterface(mw middleware) {
	r.middlewares = append(r.middlewares, mw)
}
<commit_msg>Make Use() variadic (#355)<commit_after>package mux

import "net/http"

// MiddlewareFunc is a function which receives an http.Handler and returns another http.Handler.
// Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed
// to it, and then calls the handler passed as parameter to the MiddlewareFunc.
type MiddlewareFunc func(http.Handler) http.Handler

// middleware interface is anything which implements a MiddlewareFunc named Middleware.
type middleware interface {
	Middleware(handler http.Handler) http.Handler
}

// MiddlewareFunc also implements the middleware interface.
func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler {
	return mw(handler)
}

// Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
func (r *Router) Use(mwf ...MiddlewareFunc) {
	for _, fn := range mwf {
		r.middlewares = append(r.middlewares, fn)
	}
}

// useInterface appends a middleware to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router.
func (r *Router) useInterface(mw middleware) {
	r.middlewares = append(r.middlewares, mw)
}
<|endoftext|>


<commit_before>package codetainer

import (
	"archive/tar"
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"net/url"
	"os"
	"time"

	docker "github.com/fsouza/go-dockerclient"
	"github.com/gorilla/schema"
)

func parseObjectFromForm(p interface{}, form url.Values) error {
	decoder := schema.NewDecoder()
	// r.PostForm is a map of our POST form values
	err := decoder.Decode(p, form)
	return err
}

//
// Container image.
//
// swagger:parameters imageCreate
type CodetainerImage struct {
	Id                  string    `xorm:"varchar(128) not null unique" json:"id" schema:"id"`
	DefaultStartCommand string    `json:"command" schema:"command"`
	Description         string    `json:"description" schema:"description"`
	Tags                []string  `schema:"-"`
	CreatedAt           time.Time `schema:"-"`
	UpdatedAt           time.Time `schema:"-"`
	Enabled             bool
}

// func (img *CodetainerImage) Parse(form url.Values) error {
// decoder := schema.NewDecoder()
// // r.PostForm is a map of our POST form values
// err := decoder.Decode(img, form)
// return err
// }

func (img *CodetainerImage) Register(db *Database) error {
	// check if image is in docker
	image := lookupImageInDocker(img.Id)

	if image != nil {
		if img.DefaultStartCommand == "" {
			img.DefaultStartCommand = DefaultExecCommand
		}
		img.Tags = image.RepoTags
		img.Enabled = true

		Log.Info("Registering New Image: ", img)
		_, err := db.engine.Insert(img)
		return err

	} else {
		return errors.New("No image found in docker: " + img.Id)
	}

	return nil
}

func createTarFile(fileData []byte, fileName string) (*bytes.Buffer, error) {
	buf := new(bytes.Buffer)
	tw := tar.NewWriter(buf)

	var file = struct {
		Name string
		Body []byte
	}{Name: fileName, Body: fileData}

	hdr := &tar.Header{
		Name: file.Name,
		Mode: 0600,
		Size: int64(len(file.Body)),
	}
	if err := tw.WriteHeader(hdr); err != nil {
		return nil, err
	}
	if _, err := tw.Write(file.Body); err != nil {
		return nil, err
	}

	if err := tw.Close(); err != nil {
		return nil, err
	}
	return buf, nil
}

//
// Codetainer data structure.
//
// swagger:parameters codetainerCreate
type Codetainer struct {
	Id        string    `schema:"id" json:"id"`
	Name      string    `schema:"name" json:"name"`
	ImageId   string    `schema:"image-id" json:"image-id"`
	Defunct   bool      `schema"-"`          // false if active
	Running   bool      `schema"-" xorm:"-"` // true if running
	CreatedAt time.Time `schema:"-"`
	UpdatedAt time.Time `schema:"-"`
}

func (codetainer *Codetainer) DownloadFile(filePath string) ([]byte, error) {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return nil, err
	}

	var buf bytes.Buffer
	opts := docker.CopyFromContainerOptions{
		OutputStream: &buf,
		Container:    codetainer.Id,
		Resource:     filePath,
	}
	err = client.CopyFromContainer(opts)
	if err != nil {
		return nil, err
	}
	br := bytes.NewReader(buf.Bytes())
	tr := tar.NewReader(br)
	var resultBuf bytes.Buffer
	hdr, err := tr.Next()
	if err != nil {
		return nil, err
	}
	if hdr.FileInfo().IsDir() {
		// it's tarred
		return nil, errors.New("File is a directory:" + filePath)
	}

	io.Copy(&resultBuf, tr)
	return resultBuf.Bytes(), nil

}

//
// Upload a file to a `dstPath` in a container.
//
func (codetainer *Codetainer) UploadFile(
	fileData []byte,
	fileName string,
	dstFolder string) error {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return err
	}

	buf, err := createTarFile(fileData, fileName)
	if err != nil {
		return err
	}

	fi := bytes.NewReader(buf.Bytes())

	opts := docker.PutContainerArchiveOptions{Path: dstFolder}
	opts.InputStream = fi
	Log.Debug("Writing file to codetainer")
	return client.PutContainerArchive(codetainer.Id, opts)
}

func (codetainer *Codetainer) Stop() error {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return err
	}

	return client.StopContainer(codetainer.Id, 30)
}

func (codetainer *Codetainer) Start() error {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return err
	}

	// TODO fetch config for codetainer
	return client.StartContainer(codetainer.Id, &docker.HostConfig{
		Binds: []string{
			GlobalConfig.UtilsPath() + ":/codetainer/utils:ro",
		},
	})
}

func (codetainer *Codetainer) LookupByNameOrId(id string, db *Database) error {
	codetainer.Id = id
	if codetainer.Lookup(db) != nil {
		codetainer.Name = id
		codetainer.Id = ""
		err := codetainer.Lookup(db)
		if err != nil {
			return errors.New("No codetainer found: " + id)
		}
		return err
	}
	return nil
}

func (codetainer *Codetainer) Lookup(db *Database) error {
	Log.Debug("Looking up: ", codetainer)
	has, err := db.engine.Get(codetainer)
	if err != nil {
		return err
	}
	if !has {
		return errors.New("No codetainer found: " + codetainer.Id)
	}
	return nil
}

func (codetainer *Codetainer) Create(db *Database) error {
	client, err := GlobalConfig.GetDockerClient()

	if err != nil {
		return err
	}

	image, err := db.LookupCodetainerImage(codetainer.ImageId)

	if err != nil {
		return err
	}

	if image == nil {
		return errors.New("no image found")
	}

	codetainer.ImageId = image.Id

	// TODO: all the other configs
	c, err := client.CreateContainer(docker.CreateContainerOptions{
		Name: codetainer.Name,
		Config: &docker.Config{
			OpenStdin: true,
			Tty:       true,
			Image:     image.Id,
		},
		HostConfig: &docker.HostConfig{
			Binds: []string{
				GlobalConfig.UtilsPath() + ":/codetainer/utils:ro",
			},
		},
	})

	if err != nil {
		return err
	}

	// TODO fetch config for codetainer
	err = client.StartContainer(c.ID, &docker.HostConfig{
		Binds: []string{
			GlobalConfig.UtilsPath() + ":/codetainer/utils:ro",
		},
	})

	if err != nil {
		return err
	}

	codetainer.Id = c.ID
	return codetainer.Save(db)
}

func (c *Codetainer) Save(db *Database) error {
	_, err := db.engine.Insert(c)
	return err
}

type ShortFileInfo struct {
	Name    string    `json:"name"`
	Size    int64     `json:"size"`
	IsDir   bool      `json:"is_dir"`
	IsLink  bool      `json:"is_link"`
	ModTime time.Time `json:"modified_time"`
}

func NewShortFileInfo(f os.FileInfo) *ShortFileInfo {
	fi := ShortFileInfo{}
	fi.Name = f.Name()
	fi.Size = f.Size()
	fi.IsDir = f.IsDir()
	fi.ModTime = f.ModTime()
	fi.IsLink = (f.Mode()&os.ModeType)&os.ModeSymlink > 0

	return &fi
}

func makeShortFiles(data []byte) (*[]ShortFileInfo, error) {
	files := make([]ShortFileInfo, 0)
	if err := json.Unmarshal(data, &files); err != nil {
		return nil, err
	}

	return &files, nil
}

//
// Return type for errors
//
// swagger:response APIErrorResponse
type APIErrorResponse struct {
	Error   bool   `json:"error" description:"set if an error is returned"`
	Message string `json:"message" description:"error message string"`
}

//
// TTY parameters for a codetainer
//
// swagger:parameters updateCurrentTTY
type TTY struct {
	Height int `json:"height" description:"height of tty"`
	Width  int `json:"width" description:"width of tty"`
}

//
// TTY response
//
// swagger:response TTYBody
type TTYBody struct {
	Tty TTY `json:"tty"`
}

//
// CodetainerImage response
//
// swagger:response CodetainerImageBody
type CodetainerImageBody struct {
	Image CodetainerImage `json:"image"`
}

//
// CodetainerImageList response
//
// swagger:response CodetainerImageListBody
type CodetainerImageListBody struct {
	Images []CodetainerImage `json:"images"`
}

//
// Codetainer response
//
// swagger:response CodetainerBody
type CodetainerBody struct {
	Codetainer `json:"codetainer"`
}

//
// CodetainerList response
//
// swagger:response CodetainerListBody
type CodetainerListBody struct {
	Codetainers []Codetainer `json:"codetainers"`
}
<commit_msg>no default required<commit_after>package codetainer

import (
	"archive/tar"
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"net/url"
	"os"
	"time"

	docker "github.com/fsouza/go-dockerclient"
	"github.com/gorilla/schema"
)

func parseObjectFromForm(p interface{}, form url.Values) error {
	decoder := schema.NewDecoder()
	// r.PostForm is a map of our POST form values
	err := decoder.Decode(p, form)
	return err
}

//
// Container image.
//
// swagger:parameters imageCreate
type Codeta
	Id                  string    `xorm:"varchar(128) not null unique" json:"id" schema:"id"`
	DefaultStartCommand string    `json:"command" schema:"command"`
	Description         string    `json:"description" schema:"description"`
	Tags                []string  `schema:"-"`
	CreatedAt           time.Time `schema:"-"`
	UpdatedAt           time.Time `schema:"-"`
	Enabled             bool
}

// func (img *CodetainerImage) Parse(form url.Values) error {
// decoder := schema.NewDecoder()
// // r.PostForm is a map of our POST form values
// err := decoder.Decode(img, form)
// return err
// }

func (img *CodetainerImage) Register(db *Database) error {
	// check if image is in docker
	image := lookupImageInDocker(img.Id)

	if image != nil {
		img.Tags = image.RepoTags
		img.Enabled = true

		Log.Info("Registering New Image: ", img)
		_, err := db.engine.Insert(img)
		return err

	} else {
		return errors.New("No image found in docker: " + img.Id)
	}

	return nil
}

func createTarFile(fileData []byte, fileName string) (*bytes.Buffer, error) {
	buf := new(bytes.Buffer)
	tw := tar.NewWriter(buf)

	var file = struct {
		Name string
		Body []byte
	}{Name: fileName, Body: fileData}

	hdr := &tar.Header{
		Name: file.Name,
		Mode: 0600,
		Size: int64(len(file.Body)),
	}
	if err := tw.WriteHeader(hdr); err != nil {
		return nil, err
	}
	if _, err := tw.Write(file.Body); err != nil {
		return nil, err
	}

	if err := tw.Close(); err != nil {
		return nil, err
	}
	return buf, nil
}

//
// Codetainer data structure.
//
// swagger:parameters codetainerCreate
type Codetainer struct {
	Id        string    `schema:"id" json:"id"`
	Name      string    `schema:"name" json:"name"`
	ImageId   string    `schema:"image-id" json:"image-id"`
	Defunct   bool      `schema"-"`          // false if active
	Running   bool      `schema"-" xorm:"-"` // true if running
	CreatedAt time.Time `schema:"-"`
	UpdatedAt time.Time `schema:"-"`
}

func (codetainer *Codetainer) DownloadFile(filePath string) ([]byte, error) {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return nil, err
	}

	var buf bytes.Buffer
	opts := docker.CopyFromContainerOptions{
		OutputStream: &buf,
		Container:    codetainer.Id,
		Resource:     filePath,
	}
	err = client.CopyFromContainer(opts)
	if err != nil {
		return nil, err
	}
	br := bytes.NewReader(buf.Bytes())
	tr := tar.NewReader(br)
	var resultBuf bytes.Buffer
	hdr, err := tr.Next()
	if err != nil {
		return nil, err
	}
	if hdr.FileInfo().IsDir() {
		// it's tarred
		return nil, errors.New("File is a directory:" + filePath)
	}

	io.Copy(&resultBuf, tr)
	return resultBuf.Bytes(), nil

}

//
// Upload a file to a `dstPath` in a container.
//
func (codetainer *Codetainer) UploadFile(
	fileData []byte,
	fileName string,
	dstFolder string) error {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return err
	}

	buf, err := createTarFile(fileData, fileName)
	if err != nil {
		return err
	}

	fi := bytes.NewReader(buf.Bytes())

	opts := docker.PutContainerArchiveOptions{Path: dstFolder}
	opts.InputStream = fi
	Log.Debug("Writing file to codetainer")
	return client.PutContainerArchive(codetainer.Id, opts)
}

func (codetainer *Codetainer) Stop() error {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return err
	}

	return client.StopContainer(codetainer.Id, 30)
}

func (codetainer *Codetainer) Start() error {
	client, err := GlobalConfig.GetDockerClient()
	if err != nil {
		return err
	}

	// TODO fetch config for codetainer
	return client.StartContainer(codetainer.Id, &docker.HostConfig{
		Binds: []string{
			GlobalConfig.UtilsPath() + ":/codetainer/utils:ro",
		},
	})
}

func (codetainer *Codetainer) LookupByNameOrId(id string, db *Database) error {
	codetainer.Id = id
	if codetainer.Lookup(db) != nil {
		codetainer.Name = id
		codetainer.Id = ""
		err := codetainer.Lookup(db)
		if err != nil {
			return errors.New("No codetainer found: " + id)
		}
		return err
	}
	return nil
}

func (codetainer *Codetainer) Lookup(db *Database) error {
	Log.Debug("Looking up: ", codetainer)
	has, err := db.engine.Get(codetainer)
	if err != nil {
		return err
	}
	if !has {
		return errors.New("No codetainer found: " + codetainer.Id)
	}
	return nil
}

func (codetainer *Codetainer) Create(db *Database) error {
	client, err := GlobalConfig.GetDockerClient()

	if err != nil {
		return err
	}

	image, err := db.LookupCodetainerImage(codetainer.ImageId)

	if err != nil {
		return err
	}

	if image == nil {
		return errors.New("no image found")
	}

	codetainer.ImageId = image.Id

	// TODO: all the other configs
	c, err := client.CreateContainer(docker.CreateContainerOptions{
		Name: codetainer.Name,
		Config: &docker.Config{
			OpenStdin: true,
			Tty:       true,
			Image:     image.Id,
		},
		HostConfig: &docker.HostConfig{
			Binds: []string{
				GlobalConfig.UtilsPath() + ":/codetainer/utils:ro",
			},
		},
	})

	if err != nil {
		return err
	}

	// TODO fetch config for codetainer
	err = client.StartContainer(c.ID, &docker.HostConfig{
		Binds: []string{
			GlobalConfig.UtilsPath() + ":/codetainer/utils:ro",
		},
	})

	if err != nil {
		return err
	}

	codetainer.Id = c.ID
	return codetainer.Save(db)
}

func (c *Codetainer) Save(db *Database) error {
	_, err := db.engine.Insert(c)
	return err
}

type ShortFileInfo struct {
	Name    string    `json:"name"`
	Size    int64     `json:"size"`
	IsDir   bool      `json:"is_dir"`
	IsLink  bool      `json:"is_link"`
	ModTime time.Time `json:"modified_time"`
}

func NewShortFileInfo(f os.FileInfo) *ShortFileInfo {
	fi := ShortFileInfo{}
	fi.Name = f.Name()
	fi.Size = f.Size()
	fi.IsDir = f.IsDir()
	fi.ModTime = f.ModTime()
	fi.IsLink = (f.Mode()&os.ModeType)&os.ModeSymlink > 0

	return &fi
}

func makeShortFiles(data []byte) (*[]ShortFileInfo, error) {
	files := make([]ShortFileInfo, 0)
	if err := json.Unmarshal(data, &files); err != nil {
		return nil, err
	}

	return &files, nil
}

//
// Return type for errors
//
// swagger:response APIErrorResponse
type APIErrorResponse struct {
	Error   bool   `json:"error" description:"set if an error is returned"`
	Message string `json:"message" description:"error message string"`
}

//
// TTY parameters for a codetainer
//
// swagger:parameters updateCurrentTTY
type TTY struct {
	Height int `json:"height" description:"height of tty"`
	Width  int `json:"width" description:"width of tty"`
}

//
// TTY response
//
// swagger:response TTYBody
type TTYBody struct {
	Tty TTY `json:"tty"`
}

//
// CodetainerImage response
//
// swagger:response CodetainerImageBody
type CodetainerImageBody struct {
	Image CodetainerImage `json:"image"`
}

//
// CodetainerImageList response
//
// swagger:response CodetainerImageListBody
type CodetainerImageListBody struct {
	Images []CodetainerImage `json:"images"`
}

//
// Codetainer response
//
// swagger:response CodetainerBody
type CodetainerBody struct {
	Codetainer `json:"codetainer"`
}

//
// CodetainerList response
//
// swagger:response CodetainerListBody
type CodetainerListBody struct {
	Codetainers []Codetainer `json:"codetainers"`
}
<|endoftext|>


<commit_before>package mentionbot

import (
	"log"
	"time"
)

// IDs is id list
type IDs []string

// CursoredIDs is users list with cursor info
type CursoredIDs map[string]interface{}

// NextCursorStr returns next cursor
func (ci CursoredIDs) NextCursorStr() string {
	return ci["next_cursor_str"].(string)
}

// PreviousCursorStr returns previous cursor
func (ci CursoredIDs) PreviousCursorStr() string {
	return ci["previous_cursor_str"].(string)
}

// IDs returns users list
func (ci CursoredIDs) IDs() IDs {
	results := ci["ids"].([]interface{})
	ids := make([]string, len(results))
	for i, value := range results {
		ids[i] = value.(string)
	}
	return ids
}

// User is user info
type User map[string]interface{}

// ScreenName returns users screen name
func (u User) ScreenName() string {
	return u["screen_name"].(string)
}

// Status returns users latest Status
func (u User) Status() Status {
	if u["status"] == nil {
		return nil
	}
	return Status(u["status"].(map[string]interface{}))
}

// Status is tweeted status
type Status map[string]interface{}

// Text returns tweeted text
func (s Status) Text() string {
	return s["text"].(string)
}

// CreatedAt returns tweeted time
func (s Status) CreatedAt() time.Time {
	src := s["created_at"].(string)
	out, err := time.Parse(time.RubyDate, src)
	if err != nil {
		log.Fatalf("Could not parse time: %v", err)
	}
	return out
}
<commit_msg>add statuses type<commit_after>package mentionbot

import (
	"log"
	"time"
)

// IDs is id list
type IDs []string

// CursoredIDs is users list with cursor info
type CursoredIDs map[string]interface{}

// NextCursorStr returns next cursor
func (ci CursoredIDs) NextCursorStr() string {
	return ci["next_cursor_str"].(string)
}

// PreviousCursorStr returns previous cursor
func (ci CursoredIDs) PreviousCursorStr() string {
	return ci["previous_cursor_str"].(string)
}

// IDs returns users list
func (ci CursoredIDs) IDs() IDs {
	results := ci["ids"].([]interface{})
	ids := make([]string, len(results))
	for i, value := range results {
		ids[i] = value.(string)
	}
	return ids
}

// User is user info
type User map[string]interface{}

// IDStr returns id string
func (u User) IDStr() string {
	return u["id_str"].(string)
}

// ScreenName returns users screen name
func (u User) ScreenName() string {
	return u["screen_name"].(string)
}

// Status returns users latest Status
func (u User) Status() Status {
	if u["status"] == nil {
		return nil
	}
	status := Status(u["status"].(map[string]interface{}))
	user := make(map[string]interface{})
	user["id_str"] = u.IDStr()
	user["screen_name"] = u.ScreenName()
	status["user"] = user
	return status
}

// Status is tweeted status
type Status map[string]interface{}

// Text returns tweeted text
func (s Status) Text() string {
	return s["text"].(string)
}

// CreatedAt returns tweeted time
func (s Status) CreatedAt() time.Time {
	src := s["created_at"].(string)
	out, err := time.Parse(time.RubyDate, src)
	if err != nil {
		log.Fatalf("Could not parse time: %v", err)
	}
	return out
}

// User returns tweeted user
func (s Status) User() User {
	return User(s["user"].(map[string]interface{}))
}

// Statuses type
type Statuses []Status

func (s Statuses) Len() int {
	return len(s)
}

func (s Statuses) Less(i, j int) bool {
	return s[i].CreatedAt().Before(s[j].CreatedAt())
}

func (s Statuses) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}
<|endoftext|>


<commit_before>/*
Package mdown contains functions for rendering Github flavored narkdown. Majority of this
code is borowwed from https://github.com/shurcooL/go/github_flavored_markdown. Some aspects have
been changed to meet my needs.
*/
package mdown

import "github.com/gernest/github_flavored_markdown"

// Markdown renders GitHub Flavored Markdown text.
func Markdown(text []byte) []byte {
	return github_flavored_markdown.Markdown(text)
}
<commit_msg>cleanup<commit_after>package mdown

import "github.com/gernest/github_flavored_markdown"

// Markdown renders GitHub Flavored Markdown text.
func Markdown(text []byte) []byte {
	return github_flavored_markdown.Markdown(text)
}
<|endoftext|>


<commit_before>// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package orbit

import (
	"fmt"
	"path"

	"github.com/robertkrimen/otto"
)

var (
	beg = "(function(module) { var require = module.require; var exports = module.exports; var __dirname = module.__dirname; var __filename = module.__filename;"
	end = "})"
)

func null() module {
	return func(ctx *Orbit) (val otto.Value, err error) {
		return otto.UndefinedValue(), nil
	}
}

func load(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		// Check loaded modules
		if module, ok := ctx.modules[name]; ok {
			return module, nil
		}

		// Check global modules
		if module, ok := modules[name]; ok {
			return module(ctx)
		}

		ctx.modules[name], err = find(name, fold)(ctx)

		return ctx.modules[name], err

	}
}

func find(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if len(name) == 0 {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		var files []string

		if path.IsAbs(name) == true {
			if path.Ext(name) != "" {
				files = append(files, name)
			}
			if path.Ext(name) == "" {
				files = append(files, name+".js")
				files = append(files, path.Join(name, "index.js"))
			}
		}

		if path.IsAbs(name) == false {
			if path.Ext(name) != "" {
				files = append(files, path.Join(fold, name))
			}
			if path.Ext(name) == "" {
				files = append(files, path.Join(fold, name)+".js")
				files = append(files, path.Join(fold, name, "index.js"))
			}
		}

		code, file, err := finder(ctx, files)
		if err != nil {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		return exec(code, file)(ctx)

	}
}

func main(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(run, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}

func exec(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if path.Ext(full) == ".json" {
			return ctx.Call("JSON.parse", nil, fmt.Sprintf("%s", code))
		}

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(run, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}
<commit_msg>Ensure 'this' context of each module is module.exports<commit_after>// Copyright © 2016 Abcum Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package orbit

import (
	"fmt"
	"path"

	"github.com/robertkrimen/otto"
)

var (
	beg = "(function(module) { var require = module.require; var exports = module.exports; var __dirname = module.__dirname; var __filename = module.__filename;"
	end = "})"
)

func null() module {
	return func(ctx *Orbit) (val otto.Value, err error) {
		return otto.UndefinedValue(), nil
	}
}

func load(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		// Check loaded modules
		if module, ok := ctx.modules[name]; ok {
			return module, nil
		}

		// Check global modules
		if module, ok := modules[name]; ok {
			return module(ctx)
		}

		ctx.modules[name], err = find(name, fold)(ctx)

		return ctx.modules[name], err

	}
}

func find(name string, fold string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if len(name) == 0 {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		var files []string

		if path.IsAbs(name) == true {
			if path.Ext(name) != "" {
				files = append(files, name)
			}
			if path.Ext(name) == "" {
				files = append(files, name+".js")
				files = append(files, path.Join(name, "index.js"))
			}
		}

		if path.IsAbs(name) == false {
			if path.Ext(name) != "" {
				files = append(files, path.Join(fold, name))
			}
			if path.Ext(name) == "" {
				files = append(files, path.Join(fold, name)+".js")
				files = append(files, path.Join(fold, name, "index.js"))
			}
		}

		code, file, err := finder(ctx, files)
		if err != nil {
			panic(ctx.MakeCustomError("Error", fmt.Sprintf("Cannot find module '%s'", name)))
		}

		return exec(code, file)(ctx)

	}
}

func main(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		slf, _ := module.Get("exports")

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(slf, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}

func exec(code interface{}, full string) module {
	return func(ctx *Orbit) (val otto.Value, err error) {

		if path.Ext(full) == ".json" {
			return ctx.Call("JSON.parse", nil, fmt.Sprintf("%s", code))
		}

		fold, file := path.Split(full)

		script := fmt.Sprintf("%s\n%s\n%s", beg, code, end)

		module, _ := ctx.Object(`({ exports: {} })`)

		module.Set("id", full)
		module.Set("loaded", true)
		module.Set("filename", full)
		module.Set("__dirname", fold)
		module.Set("__filename", file)

		module.Set("require", func(call otto.FunctionCall) otto.Value {
			arg := call.Argument(0).String()
			val, err := load(arg, fold)(ctx)
			if err != nil {
				panic(err)
			}
			return val
		})

		slf, _ := module.Get("exports")

		sct, err := ctx.Compile(full, script)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		run, err := ctx.Otto.Run(sct)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		ret, err := run.Call(slf, module)
		if err != nil {
			return otto.UndefinedValue(), err
		}

		exp, err := module.Get("exports")
		if err != nil {
			return otto.UndefinedValue(), err
		}

		if exp.IsFunction() {
			val, err = module.Call("exports")
			return
		}

		if exp.IsDefined() {
			val = exp
			return
		}

		if ret.IsDefined() {
			val = ret
			return
		}

		return

	}

}
<|endoftext|>


<commit_before>package repository

import (
	"github.com/lib/pq"
	"github.com/syou6162/go-active-learning/lib/model"
)

func (r *repository) UpdateOrCreateReferringTweets(e *model.Example) error {
	if e.ReferringTweets == nil || len(*e.ReferringTweets) == 0 {
		return nil
	}

	tmp, err := r.FindExampleByUlr(e.Url)
	if err != nil {
		return err
	}
	id := tmp.Id

	for _, t := range *e.ReferringTweets {
		t.ExampleId = id
		if _, err = r.db.NamedExec(`
INSERT INTO tweet
( example_id,  created_at,  id_str,  full_text,  favorite_count,  retweet_count,  lang,  screen_name,  name,  profile_image_url,  label,  score)
VALUES
(:example_id, :created_at, :id_str, :full_text, :favorite_count, :retweet_count, :lang, :screen_name, :name, :profile_image_url, :label, :score)
ON CONFLICT (example_id, id_str)
DO UPDATE SET
favorite_count = :favorite_count,  retweet_count = :retweet_count, label = :label
WHERE
EXCLUDED.label != 0 AND tweet.label != EXCLUDED.label
;`, t); err != nil {
			return err
		}
	}
	return nil
}

func (r *repository) UpdateTweetLabel(exampleId int, idStr string, label model.LabelType) error {
	if _, err := r.db.Exec(`UPDATE tweet SET label = $1 WHERE example_id = $2 AND id_str = $3;`, label, exampleId, idStr); err != nil {
		return err
	}
	return nil
}

func (r *repository) SearchReferringTweetsList(examples model.Examples) (map[int]model.ReferringTweets, error) {
	referringTweetsByExampleId := make(map[int]model.ReferringTweets)

	referringTweets := model.ReferringTweets{}
	exampleIds := make([]int, 0)
	for _, e := range examples {
		exampleIds = append(exampleIds, e.Id)
	}

	query := `SELECT * FROM tweet WHERE example_id = ANY($1) AND label != -1 AND score > -1.0 AND (lang = 'en' OR lang = 'ja') ORDER BY favorite_count DESC;`
	err := r.db.Select(&referringTweets, query, pq.Array(exampleIds))
	if err != nil {
		return referringTweetsByExampleId, err
	}

	for _, t := range referringTweets {
		referringTweetsByExampleId[t.ExampleId] = append(referringTweetsByExampleId[t.ExampleId], t)
	}
	return referringTweetsByExampleId, nil
}

func (r *repository) SearchReferringTweets(limit int) (model.ReferringTweets, error) {
	referringTweets := model.ReferringTweets{}
	query := `SELECT * FROM tweet WHERE lang = 'en' OR lang = 'ja' ORDER BY created_at DESC LIMIT $1;`
	err := r.db.Select(&referringTweets, query, limit)
	if err != nil {
		return referringTweets, err
	}
	return referringTweets, nil
}

func (r *repository) searchReferringTweetsByLabel(label model.LabelType, limit int) (model.ReferringTweets, error) {
	referringTweets := model.ReferringTweets{}
	query := `
SELECT * FROM tweet WHERE id IN
  (SELECT id FROM
    (SELECT tweet.id, ROW_NUMBER() OVER(partition BY example_id ORDER BY favorite_count DESC) AS rank
    FROM tweet
    INNER JOIN example ON tweet.example_id = example.id
    WHERE tweet.label = $1 AND (lang = 'en' OR lang = 'ja') AND (example.label = 1 OR example.label = 0)
  ) AS t WHERE rank < 5)
ORDER BY created_at DESC LIMIT $2
;`
	err := r.db.Select(&referringTweets, query, label, limit)
	if err != nil {
		return referringTweets, err
	}
	return referringTweets, nil
}

func (r *repository) SearchPositiveReferringTweets(limit int) (model.ReferringTweets, error) {
	return r.searchReferringTweetsByLabel(model.POSITIVE, limit)
}

func (r *repository) SearchNegativeReferringTweets(limit int) (model.ReferringTweets, error) {
	return r.searchReferringTweetsByLabel(model.NEGATIVE, limit)
}

func (r *repository) SearchUnlabeledReferringTweets(limit int) (model.ReferringTweets, error) {
	return r.searchReferringTweetsByLabel(model.UNLABELED, limit)
}

func (r *repository) FindReferringTweets(e *model.Example) (model.ReferringTweets, error) {
	referringTweets := model.ReferringTweets{}

	query := `SELECT * FROM tweet WHERE example_id = $1 AND label != -1 AND score > 0.0 AND (lang = 'en' OR lang = 'ja') ORDER BY favorite_count DESC;`
	err := r.db.Select(&referringTweets, query, e.Id)
	if err != nil {
		return referringTweets, err
	}
	return referringTweets, nil
}
<commit_msg>個数減らす<commit_after>package repository

import (
	"github.com/lib/pq"
	"github.com/syou6162/go-active-learning/lib/model"
)

func (r *repository) UpdateOrCreateReferringTweets(e *model.Example) error {
	if e.ReferringTweets == nil || len(*e.ReferringTweets) == 0 {
		return nil
	}

	tmp, err := r.FindExampleByUlr(e.Url)
	if err != nil {
		return err
	}
	id := tmp.Id

	for _, t := range *e.ReferringTweets {
		t.ExampleId = id
		if _, err = r.db.NamedExec(`
INSERT INTO tweet
( example_id,  created_at,  id_str,  full_text,  favorite_count,  retweet_count,  lang,  screen_name,  name,  profile_image_url,  label,  score)
VALUES
(:example_id, :created_at, :id_str, :full_text, :favorite_count, :retweet_count, :lang, :screen_name, :name, :profile_image_url, :label, :score)
ON CONFLICT (example_id, id_str)
DO UPDATE SET
favorite_count = :favorite_count,  retweet_count = :retweet_count, label = :label
WHERE
EXCLUDED.label != 0 AND tweet.label != EXCLUDED.label
;`, t); err != nil {
			return err
		}
	}
	return nil
}

func (r *repository) UpdateTweetLabel(exampleId int, idStr string, label model.LabelType) error {
	if _, err := r.db.Exec(`UPDATE tweet SET label = $1 WHERE example_id = $2 AND id_str = $3;`, label, exampleId, idStr); err != nil {
		return err
	}
	return nil
}

func (r *repository) SearchReferringTweetsList(examples model.Examples) (map[int]model.ReferringTweets, error) {
	referringTweetsByExampleId := make(map[int]model.ReferringTweets)

	referringTweets := model.ReferringTweets{}
	exampleIds := make([]int, 0)
	for _, e := range examples {
		exampleIds = append(exampleIds, e.Id)
	}

	query := `SELECT * FROM tweet WHERE example_id = ANY($1) AND label != -1 AND score > -1.0 AND (lang = 'en' OR lang = 'ja') ORDER BY favorite_count DESC;`
	err := r.db.Select(&referringTweets, query, pq.Array(exampleIds))
	if err != nil {
		return referringTweetsByExampleId, err
	}

	for _, t := range referringTweets {
		referringTweetsByExampleId[t.ExampleId] = append(referringTweetsByExampleId[t.ExampleId], t)
	}
	return referringTweetsByExampleId, nil
}

func (r *repository) SearchReferringTweets(limit int) (model.ReferringTweets, error) {
	referringTweets := model.ReferringTweets{}
	query := `SELECT * FROM tweet WHERE lang = 'en' OR lang = 'ja' ORDER BY created_at DESC LIMIT $1;`
	err := r.db.Select(&referringTweets, query, limit)
	if err != nil {
		return referringTweets, err
	}
	return referringTweets, nil
}

func (r *repository) searchReferringTweetsByLabel(label model.LabelType, limit int) (model.ReferringTweets, error) {
	referringTweets := model.ReferringTweets{}
	query := `
SELECT * FROM tweet WHERE id IN
  (SELECT id FROM
    (SELECT tweet.id, ROW_NUMBER() OVER(partition BY example_id ORDER BY favorite_count DESC) AS rank
    FROM tweet
    INNER JOIN example ON tweet.example_id = example.id
    WHERE tweet.label = $1 AND (lang = 'en' OR lang = 'ja') AND (example.label = 1 OR example.label = 0)
  ) AS t WHERE rank < 4)
ORDER BY created_at DESC LIMIT $2
;`
	err := r.db.Select(&referringTweets, query, label, limit)
	if err != nil {
		return referringTweets, err
	}
	return referringTweets, nil
}

func (r *repository) SearchPositiveReferringTweets(limit int) (model.ReferringTweets, error) {
	return r.searchReferringTweetsByLabel(model.POSITIVE, limit)
}

func (r *repository) SearchNegativeReferringTweets(limit int) (model.ReferringTweets, error) {
	return r.searchReferringTweetsByLabel(model.NEGATIVE, limit)
}

func (r *repository) SearchUnlabeledReferringTweets(limit int) (model.ReferringTweets, error) {
	return r.searchReferringTweetsByLabel(model.UNLABELED, limit)
}

func (r *repository) FindReferringTweets(e *model.Example) (model.ReferringTweets, error) {
	referringTweets := model.ReferringTweets{}

	query := `SELECT * FROM tweet WHERE example_id = $1 AND label != -1 AND score > 0.0 AND (lang = 'en' OR lang = 'ja') ORDER BY favorite_count DESC;`
	err := r.db.Select(&referringTweets, query, e.Id)
	if err != nil {
		return referringTweets, err
	}
	return referringTweets, nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/codegangsta/cli"
	"github.com/monder/kaylee/commands"
	"os"
)

func main() {
	app := cli.NewApp()
	app.Version = "0.1.0"
	app.Usage = "Container orchestration system for fleet"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "etcd-endpoints",
			Value:  "http://127.0.0.1:4001,http://127.0.0.1:2379",
			Usage:  "a comma-delimited list of etcd endpoints",
			EnvVar: "ETCDCTL_ENDPOINT",
		},
		cli.StringFlag{
			Name:  "etcd-prefix",
			Value: "/kaylee",
			Usage: "a keyspace for unit data in etcd",
		},
	}

	app.Commands = []cli.Command{
		commands.NewServerCommand(),
		commands.NewRunCommand(),
		commands.NewLsCommand(),
		commands.NewRestartCommand(),
	}

	app.Run(os.Args)
}
<commit_msg>v0.3.0<commit_after>package main

import (
	"github.com/codegangsta/cli"
	"github.com/monder/kaylee/commands"
	"os"
)

func main() {
	app := cli.NewApp()
	app.Version = "0.3.0"
	app.Usage = "Container orchestration system for fleet"

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:   "etcd-endpoints",
			Value:  "http://127.0.0.1:4001,http://127.0.0.1:2379",
			Usage:  "a comma-delimited list of etcd endpoints",
			EnvVar: "ETCDCTL_ENDPOINT",
		},
		cli.StringFlag{
			Name:  "etcd-prefix",
			Value: "/kaylee",
			Usage: "a keyspace for unit data in etcd",
		},
	}

	app.Commands = []cli.Command{
		commands.NewServerCommand(),
		commands.NewRunCommand(),
		commands.NewLsCommand(),
		commands.NewRestartCommand(),
	}

	app.Run(os.Args)
}
<|endoftext|>


<commit_before>package kdtree

type Point interface {
	Dim() int
	GetValue(dim int) float64
	Distance(p Point) float64
}

func NewKDTree(points []Point) *KDTree {
	return nil
}

type KDTreeNode struct {
	axis           int
	splittingPlane float64
	leftChild      *KDTreeNode
	rightChild     *KDTreeNode
}

type KDTree struct {
	root *KDTreeNode
	dim  int
}

func (t *KDTree) Dim() int {
	return t.dim
}
<commit_msg>NewKDTree<commit_after>package kdtree

type Point interface {
	Dim() int
	GetValue(dim int) float64
	Distance(p Point) float64
}

func NewKDTree(points []Point) *KDTree {
	if len(points) == 0 {
		return nil
	}
	ret := &KDTree{
		dim: points[0].Dim(),
	}
	// TODO
	return ret
}

func newKDTree(points []Point, depth int) *KDTreeNode {
	if len(points) == 0 {
		return nil
	}
	dim := points[0].Dim()
	if len(points) == 1 {
		return &KDTreeNode{
			axis:           depth % dim,
			splittingPoint: points[0],
			leftChild:      nil,
			rightChild:     nil,
		}
	}
	// TODO
	return nil
}

func selectSplittingPoint(points []Point, depth int) Point {
	// TODO
	return nil
}

type KDTreeNode struct {
	axis           int
	splittingPoint Point
	leftChild      *KDTreeNode
	rightChild     *KDTreeNode
}

type KDTree struct {
	root *KDTreeNode
	dim  int
}

func (t *KDTree) Dim() int {
	return t.dim
}
<|endoftext|>