<commit_before>package api

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/martinp/atbapi/atb"
	"github.com/pmylund/go-cache"
	"log"
	"net/http"
	"strconv"
	"time"
)

type Api struct {
	Client atb.Client
	cache  *cache.Cache
	expiration
}

type expiration struct {
	departures time.Duration
	stops      time.Duration
}

func marshal(data interface{}, indent bool) ([]byte, error) {
	if indent {
		return json.MarshalIndent(data, "", "  ")
	}
	return json.Marshal(data)
}

func (a *Api) getBusStops() (BusStops, error) {
	const cacheKey = "stops"
	cached, ok := a.cache.Get(cacheKey)
	if ok {
		cachedBusStops, ok := cached.(BusStops)
		if !ok {
			return BusStops{}, fmt.Errorf(
				"type assertion of cached value failed")
		}
		return cachedBusStops, nil
	}
	atbBusStops, err := a.Client.GetBusStops()
	if err != nil {
		return BusStops{}, err
	}
	busStops, err := convertBusStops(atbBusStops)
	if err != nil {
		return BusStops{}, err
	}
	// Create a map of nodeIds
	busStops.nodeIds = make(map[int]struct{}, len(busStops.Stops))
	for _, s := range busStops.Stops {
		busStops.nodeIds[s.NodeId] = struct{}{}
	}
	a.cache.Set(cacheKey, busStops, a.expiration.stops)
	return busStops, nil
}

func (a *Api) getDepartures(nodeId int) (Departures, error) {
	cacheKey := strconv.Itoa(nodeId)
	cached, ok := a.cache.Get(cacheKey)
	if ok {
		cachedDepartures, ok := cached.(Departures)
		if !ok {
			return Departures{}, fmt.Errorf(
				"type assertion of cached value failed")
		}
		return cachedDepartures, nil
	}
	forecasts, err := a.Client.GetRealTimeForecast(nodeId)
	if err != nil {
		return Departures{}, err
	}
	departures, err := convertForecasts(forecasts)
	if err != nil {
		return Departures{}, err
	}
	a.cache.Set(cacheKey, departures, cache.DefaultExpiration)
	return departures, nil
}

func (a *Api) BusStopsHandler(w http.ResponseWriter, req *http.Request) *Error {
	busStops, err := a.getBusStops()
	if err != nil {
		log.Print(err)
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "failed to get bus stops from atb",
		}
	}
	jsonBlob, err := marshal(busStops, context.Get(req, "indent").(bool))
	if err != nil {
		log.Print(err)
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "failed to marshal bus stops",
		}
	}
	w.Write(jsonBlob)
	return nil
}

func (a *Api) DeparturesHandler(w http.ResponseWriter, req *http.Request) *Error {
	vars := mux.Vars(req)
	nodeId, err := strconv.Atoi(vars["nodeId"])
	if err != nil {
		log.Print(err)
		return &Error{
			err:     err,
			Status:  http.StatusBadRequest,
			Message: "missing or invalid nodeId",
		}
	}
	busStops, err := a.getBusStops()
	if err != nil {
		log.Print(err)
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "could not get bus stops from atb",
		}
	}
	_, knownBusStop := busStops.nodeIds[nodeId]
	if !knownBusStop {
		msg := fmt.Sprintf("bus stop with nodeId=%d not found", nodeId)
		return &Error{
			err:     err,
			Status:  http.StatusNotFound,
			Message: msg,
		}
	}
	departures, err := a.getDepartures(nodeId)
	if err != nil {
		log.Print(err)
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "could not get departures from atb",
		}
	}
	jsonBlob, err := marshal(departures, context.Get(req, "indent").(bool))
	if err != nil {
		log.Print(err)
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "failed to marshal departures",
		}
	}
	w.Write(jsonBlob)
	return nil
}

func (a *Api) NotFoundHandler(w http.ResponseWriter, req *http.Request) *Error {
	return &Error{
		err:     nil,
		Status:  http.StatusNotFound,
		Message: "route not found",
	}
}

func New(client atb.Client, stopsExpiration, depExpiration time.Duration) Api {
	cache := cache.New(depExpiration, 30*time.Second)
	return Api{
		Client: client,
		cache:  cache,
		expiration: expiration{
			stops:      stopsExpiration,
			departures: depExpiration,
		},
	}
}

type appHandler func(http.ResponseWriter, *http.Request) *Error

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if e := fn(w, r); e != nil { // e is *Error, not os.Error.
		if e.err != nil {
			log.Print(e.err)
		}
		data, err := marshal(e, true)
		if err != nil {
			// Should never happen
			panic(err)
		}
		w.WriteHeader(e.Status)
		w.Write(data)
	}
}

func requestFilter(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, indent := r.URL.Query()["pretty"]
		context.Set(r, "indent", indent)
		w.Header().Set("Content-Type", "application/json")
		next.ServeHTTP(w, r)
	})
}

func (a *Api) ListenAndServe(addr string) error {
	r := mux.NewRouter()
	r.Handle("/api/v1/busstops", appHandler(a.BusStopsHandler))
	r.Handle("/api/v1/departures/{nodeId:[0-9]+}",
		appHandler(a.DeparturesHandler))
	r.NotFoundHandler = appHandler(a.NotFoundHandler)
	http.Handle("/", requestFilter(r))
	return http.ListenAndServe(addr, nil)
}
<commit_msg>Do not log error multiple times<commit_after>package api

import (
	"encoding/json"
	"fmt"
	"github.com/gorilla/context"
	"github.com/gorilla/mux"
	"github.com/martinp/atbapi/atb"
	"github.com/pmylund/go-cache"
	"log"
	"net/http"
	"strconv"
	"time"
)

type Api struct {
	Client atb.Client
	cache  *cache.Cache
	expiration
}

type expiration struct {
	departures time.Duration
	stops      time.Duration
}

func marshal(data interface{}, indent bool) ([]byte, error) {
	if indent {
		return json.MarshalIndent(data, "", "  ")
	}
	return json.Marshal(data)
}

func (a *Api) getBusStops() (BusStops, error) {
	const cacheKey = "stops"
	cached, ok := a.cache.Get(cacheKey)
	if ok {
		cachedBusStops, ok := cached.(BusStops)
		if !ok {
			return BusStops{}, fmt.Errorf(
				"type assertion of cached value failed")
		}
		return cachedBusStops, nil
	}
	atbBusStops, err := a.Client.GetBusStops()
	if err != nil {
		return BusStops{}, err
	}
	busStops, err := convertBusStops(atbBusStops)
	if err != nil {
		return BusStops{}, err
	}
	// Create a map of nodeIds
	busStops.nodeIds = make(map[int]struct{}, len(busStops.Stops))
	for _, s := range busStops.Stops {
		busStops.nodeIds[s.NodeId] = struct{}{}
	}
	a.cache.Set(cacheKey, busStops, a.expiration.stops)
	return busStops, nil
}

func (a *Api) getDepartures(nodeId int) (Departures, error) {
	cacheKey := strconv.Itoa(nodeId)
	cached, ok := a.cache.Get(cacheKey)
	if ok {
		cachedDepartures, ok := cached.(Departures)
		if !ok {
			return Departures{}, fmt.Errorf(
				"type assertion of cached value failed")
		}
		return cachedDepartures, nil
	}
	forecasts, err := a.Client.GetRealTimeForecast(nodeId)
	if err != nil {
		return Departures{}, err
	}
	departures, err := convertForecasts(forecasts)
	if err != nil {
		return Departures{}, err
	}
	a.cache.Set(cacheKey, departures, cache.DefaultExpiration)
	return departures, nil
}

func (a *Api) BusStopsHandler(w http.ResponseWriter, req *http.Request) *Error {
	busStops, err := a.getBusStops()
	if err != nil {
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "failed to get bus stops from atb",
		}
	}
	jsonBlob, err := marshal(busStops, context.Get(req, "indent").(bool))
	if err != nil {
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "failed to marshal bus stops",
		}
	}
	w.Write(jsonBlob)
	return nil
}

func (a *Api) DeparturesHandler(w http.ResponseWriter, req *http.Request) *Error {
	vars := mux.Vars(req)
	nodeId, err := strconv.Atoi(vars["nodeId"])
	if err != nil {
		return &Error{
			err:     err,
			Status:  http.StatusBadRequest,
			Message: "missing or invalid nodeId",
		}
	}
	busStops, err := a.getBusStops()
	if err != nil {
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "could not get bus stops from atb",
		}
	}
	_, knownBusStop := busStops.nodeIds[nodeId]
	if !knownBusStop {
		msg := fmt.Sprintf("bus stop with nodeId=%d not found", nodeId)
		return &Error{
			err:     err,
			Status:  http.StatusNotFound,
			Message: msg,
		}
	}
	departures, err := a.getDepartures(nodeId)
	if err != nil {
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "could not get departures from atb",
		}
	}
	jsonBlob, err := marshal(departures, context.Get(req, "indent").(bool))
	if err != nil {
		return &Error{
			err:     err,
			Status:  http.StatusInternalServerError,
			Message: "failed to marshal departures",
		}
	}
	w.Write(jsonBlob)
	return nil
}

func (a *Api) NotFoundHandler(w http.ResponseWriter, req *http.Request) *Error {
	return &Error{
		err:     nil,
		Status:  http.StatusNotFound,
		Message: "route not found",
	}
}

func New(client atb.Client, stopsExpiration, depExpiration time.Duration) Api {
	cache := cache.New(depExpiration, 30*time.Second)
	return Api{
		Client: client,
		cache:  cache,
		expiration: expiration{
			stops:      stopsExpiration,
			departures: depExpiration,
		},
	}
}

type appHandler func(http.ResponseWriter, *http.Request) *Error

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if e := fn(w, r); e != nil { // e is *Error, not os.Error.
		if e.err != nil {
			log.Print(e.err)
		}
		data, err := marshal(e, true)
		if err != nil {
			// Should never happen
			panic(err)
		}
		w.WriteHeader(e.Status)
		w.Write(data)
	}
}

func requestFilter(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, indent := r.URL.Query()["pretty"]
		context.Set(r, "indent", indent)
		w.Header().Set("Content-Type", "application/json")
		next.ServeHTTP(w, r)
	})
}

func (a *Api) ListenAndServe(addr string) error {
	r := mux.NewRouter()
	r.Handle("/api/v1/busstops", appHandler(a.BusStopsHandler))
	r.Handle("/api/v1/departures/{nodeId:[0-9]+}",
		appHandler(a.DeparturesHandler))
	r.NotFoundHandler = appHandler(a.NotFoundHandler)
	http.Handle("/", requestFilter(r))
	return http.ListenAndServe(addr, nil)
}
<|endoftext|>


<commit_before>/*
 *  Bulldozer Framework
 *  Copyright (C) DesertBit
 */

package bulldozer

import (
	_ "code.desertbit.com/bulldozer/bulldozer/plugins"

	tr "code.desertbit.com/bulldozer/bulldozer/translate"

	"code.desertbit.com/bulldozer/bulldozer/auth"
	"code.desertbit.com/bulldozer/bulldozer/controlpanel"
	"code.desertbit.com/bulldozer/bulldozer/database"
	"code.desertbit.com/bulldozer/bulldozer/log"
	"code.desertbit.com/bulldozer/bulldozer/mux"
	"code.desertbit.com/bulldozer/bulldozer/sessions"
	"code.desertbit.com/bulldozer/bulldozer/settings"
	"code.desertbit.com/bulldozer/bulldozer/store"
	"code.desertbit.com/bulldozer/bulldozer/templates"
	"code.desertbit.com/bulldozer/bulldozer/topbar"
	"code.desertbit.com/bulldozer/bulldozer/utils"

	"flag"
	"fmt"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"
)

const (
	InterruptExitCode = 5
)

var (
	isInitialized   bool = false
	isInitializing  bool = false
	isShuttdingDown bool = false

	releaseMutex sync.Mutex
)

//##############//
//### Public ###//
//##############//

// Init initializes the bulldozer workspace and settings.
// If you want to set any bulldozer settings, then do this before calling this method!
func Init() {
	// Parameters.
	var paramSettingsPath string
	var setupDB bool

	// Set the flags
	isInitialized = true
	isInitializing = true

	// Bind the variables to the flags.
	flag.StringVar(&paramSettingsPath, "settings", paramSettingsPath, "set the path to an additional settings file.")
	flag.BoolVar(&setupDB, "setup", false, "setup the database structure.")

	// Set the maximum number of CPUs that can be executing simultaneously.
	if settings.Settings.AutoSetGOMAXPROCS {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}

	// Parse the flags
	if settings.Settings.AutoParseFlags {
		flag.Parse()
	}

	// Catch interrupt signals
	if settings.Settings.AutoCatchInterrupts {
		go func() {
			// Wait for the signal
			sigchan := make(chan os.Signal, 10)
			signal.Notify(sigchan, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGKILL)
			<-sigchan

			fmt.Println("Exiting...")

			// If terminated while initializing, just sleep
			// for a short timeout, to not interrupt the initialization process.
			if isInitializing {
				time.Sleep(5 * time.Second)
			}

			// First cleanup
			release()

			// Exit the application
			os.Exit(InterruptExitCode)
		}()
	}

	// Load the settings file if it exists in the project folder.
	settingsPath := settings.Settings.WorkingPath + settings.DefaultSettingsFileName
	exists, err := utils.Exists(settingsPath)
	if err != nil {
		log.L.Fatal(err)
	}
	if exists {
		if err = settings.Load(settingsPath); err != nil {
			log.L.Fatal(err)
		}
	}

	// Load the addional settings file.
	if len(paramSettingsPath) > 0 {
		if err = settings.Load(paramSettingsPath); err != nil {
			log.L.Fatal(err)
		}
	}

	// Prepare the settings.
	err = settings.Prepare()
	if err != nil {
		log.L.Fatal(err)
	}

	// Create the important directories if they don't exist
	if err = createDirectories(); err != nil {
		log.L.Fatal(err)
	}

	// Add the translation paths and load all translation files.
	tr.Add(settings.Settings.BulldozerTranslationPath)
	tr.Add(settings.Settings.TranslationPath)
	tr.Load()

	// Initialize the bulldozer sub packages.
	sessions.Init(backendI)
	mux.Init(backendI)

	// Connect to the database server.
	if err = database.Connect(); err != nil {
		log.L.Fatal(err)
	}

	// Setup the database structure if requested.
	if setupDB {
		if err = database.Setup(); err != nil {
			log.L.Fatal(err)
		}

		// Exit the application.
		os.Exit(0)
	}

	// Initialize the store package.
	store.Init()

	// Load the bulldozer templates to the bulldozer namespace.
	err = templates.Load("bud", settings.Settings.BulldozerTemplatesPath, settings.Settings.BulldozerCoreTemplatesPath)
	if err != nil {
		log.L.Fatal(err)
	}

	// Initialize the authentication package.
	if err = auth.Init(); err != nil {
		log.L.Fatal(err)
	}

	// Initialize the topbar package.
	if err = topbar.Init(); err != nil {
		log.L.Fatal(err)
	}

	// Initialize the control center package.
	if err = controlpanel.Init(); err != nil {
		log.L.Fatal(err)
	}

	// Load the templates in the project templates directory.
	// Don't handle the parse errors here. It will be shown by the server.
	templates.Load("", settings.Settings.TemplatesPath)

	// Call the init hooks.
	if err = triggerOnInit(); err != nil {
		log.L.Fatalf("init hook error: %v", err)
	}

	// Build the scss files.
	buildScss()

	// Watch the scss files and rebuild them on changes.
	watchScss()

	// Update the flag.
	isInitializing = false
}

// Bulldoze starts the Bulldozer server
func Bulldoze() {
	// Cleanup on exit
	defer release()

	// Check if the Init() method was called. This is a must!
	if !isInitialized {
		log.L.Fatalf("failed to bulldoze: bulldozer is not initialized! It is required to call the bulldoze.Init method before bulldozing!")
	}

	// Start the server
	err := serve()
	if err != nil {
		log.L.Fatal(err)
	}
}

//###############//
//### Private ###//
//###############//

func release() {
	// Lock the mutex
	releaseMutex.Lock()
	defer releaseMutex.Unlock()

	// Check if already released
	if isShuttdingDown {
		return
	}

	// Set the flag
	isShuttdingDown = true

	// Stop the filewatcher
	scssFileWatcher.Close()

	// Release the bulldozer sub packages
	sessions.Release()
	tr.Release()
	auth.Release()
	store.Release()

	// Close the database
	database.Close()

	// Just wait for a moment before exiting to be
	// sure, all defers get called and the program
	// makes a clean exit.
	time.Sleep(5150 * time.Millisecond)
}

// Create important folders if missing
func createDirectories() (err error) {
	// Create the slice of folder paths
	dirs := [...]string{
		settings.Settings.TmpPath,
		settings.Settings.PublicPath,
		settings.Settings.PagesPath,
		settings.Settings.TemplatesPath,
		settings.Settings.TranslationPath,
		settings.Settings.DataPath,
		settings.Settings.ScssPath,
	}

	// Create the directories
	for _, dir := range dirs {
		err = utils.MkDirIfNotExists(dir)
		if err != nil {
			return fmt.Errorf("failed to create directory: '%s': %v", dir, err)
		}
	}

	return nil
}
<commit_msg>further progress<commit_after>/*
 *  Bulldozer Framework
 *  Copyright (C) DesertBit
 */

package bulldozer

import (
	_ "code.desertbit.com/bulldozer/bulldozer/plugins"

	tr "code.desertbit.com/bulldozer/bulldozer/translate"

	"code.desertbit.com/bulldozer/bulldozer/auth"
	"code.desertbit.com/bulldozer/bulldozer/controlpanel"
	"code.desertbit.com/bulldozer/bulldozer/database"
	"code.desertbit.com/bulldozer/bulldozer/log"
	"code.desertbit.com/bulldozer/bulldozer/mux"
	"code.desertbit.com/bulldozer/bulldozer/sessions"
	"code.desertbit.com/bulldozer/bulldozer/settings"
	"code.desertbit.com/bulldozer/bulldozer/store"
	"code.desertbit.com/bulldozer/bulldozer/templates"
	"code.desertbit.com/bulldozer/bulldozer/topbar"
	"code.desertbit.com/bulldozer/bulldozer/utils"

	"flag"
	"fmt"
	"os"
	"os/signal"
	"runtime"
	"sync"
	"syscall"
	"time"
)

const (
	InterruptExitCode = 5
)

var (
	isInitialized   bool = false
	isInitializing  bool = false
	isShuttdingDown bool = false

	releaseMutex sync.Mutex
)

//##############//
//### Public ###//
//##############//

// Init initializes the bulldozer workspace and settings.
// If you want to set any bulldozer settings, then do this before calling this method!
func Init() {
	// Parameters.
	var paramSettingsPath string
	var setupDB bool

	// Set the flags
	isInitialized = true
	isInitializing = true

	// Bind the variables to the flags.
	flag.StringVar(&paramSettingsPath, "settings", paramSettingsPath, "set the path to an additional settings file.")
	flag.BoolVar(&setupDB, "setup", false, "setup the database structure.")

	// Set the maximum number of CPUs that can be executing simultaneously.
	if settings.Settings.AutoSetGOMAXPROCS {
		runtime.GOMAXPROCS(runtime.NumCPU())
	}

	// Parse the flags
	if settings.Settings.AutoParseFlags {
		flag.Parse()
	}

	// Catch interrupt signals
	if settings.Settings.AutoCatchInterrupts {
		go func() {
			// Wait for the signal
			sigchan := make(chan os.Signal, 10)
			signal.Notify(sigchan, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGKILL)
			<-sigchan

			fmt.Println("Exiting...")

			// If terminated while initializing, just sleep
			// for a short timeout, to not interrupt the initialization process.
			if isInitializing {
				time.Sleep(5 * time.Second)
			}

			// First cleanup
			release()

			// Exit the application
			os.Exit(InterruptExitCode)
		}()
	}

	// Load the settings file if it exists in the project folder.
	settingsPath := settings.Settings.WorkingPath + settings.DefaultSettingsFileName
	exists, err := utils.Exists(settingsPath)
	if err != nil {
		log.L.Fatal(err)
	}
	if exists {
		if err = settings.Load(settingsPath); err != nil {
			log.L.Fatal(err)
		}
	}

	// Load the addional settings file.
	if len(paramSettingsPath) > 0 {
		if err = settings.Load(paramSettingsPath); err != nil {
			log.L.Fatal(err)
		}
	}

	// Prepare the settings.
	err = settings.Prepare()
	if err != nil {
		log.L.Fatal(err)
	}

	// Create the important directories if they don't exist
	if err = createDirectories(); err != nil {
		log.L.Fatal(err)
	}

	// Add the translation paths and load all translation files.
	tr.Add(settings.Settings.BulldozerTranslationPath)
	tr.Add(settings.Settings.TranslationPath)
	tr.Load()

	// Initialize the bulldozer sub packages.
	sessions.Init(backendI)
	mux.Init(backendI)

	// Connect to the database server.
	if err = database.Connect(); err != nil {
		log.L.Fatal(err)
	}

	// Setup the database structure if requested.
	if setupDB {
		if err = database.Setup(); err != nil {
			log.L.Fatal(err)
		}

		// Exit the application.
		os.Exit(0)
	}

	// Initialize the store package.
	store.Init()

	// Load the bulldozer templates to the bulldozer namespace.
	err = templates.Load("bud", settings.Settings.BulldozerTemplatesPath, settings.Settings.BulldozerCoreTemplatesPath)
	if err != nil {
		log.L.Fatal(err)
	}

	// Initialize the authentication package.
	if err = auth.Init(); err != nil {
		log.L.Fatal(err)
	}

	// Initialize the topbar package.
	if err = topbar.Init(); err != nil {
		log.L.Fatal(err)
	}

	// Initialize the control center package.
	if err = controlpanel.Init(); err != nil {
		log.L.Fatal(err)
	}

	// Load the templates in the project templates directory.
	// Don't handle the parse errors here. It will be shown by the server.
	templates.Load("", settings.Settings.TemplatesPath)

	// Call the init hooks.
	if err = triggerOnInit(); err != nil {
		log.L.Fatalf("init hook error: %v", err)
	}

	// Build the scss files.
	buildScss()

	// Watch the scss files and rebuild them on changes.
	watchScss()

	// Update the flag.
	isInitializing = false
}

// Bulldoze starts the Bulldozer server
func Bulldoze() {
	// Cleanup on exit
	defer release()

	// Check if the Init() method was called. This is a must!
	if !isInitialized {
		log.L.Fatalf("failed to bulldoze: bulldozer is not initialized! It is required to call the bulldoze.Init method before bulldozing!")
	}

	// Start the server
	err := serve()
	if err != nil {
		log.L.Fatal(err)
	}
}

//###############//
//### Private ###//
//###############//

func release() {
	// Lock the mutex
	releaseMutex.Lock()
	defer releaseMutex.Unlock()

	// Check if already released
	if isShuttdingDown {
		return
	}

	// Set the flag
	isShuttdingDown = true

	// Stop the filewatcher
	scssFileWatcher.Close()

	// Release the bulldozer sub packages
	sessions.Release()
	tr.Release()
	auth.Release()
	store.Release()

	// Close the database
	database.Close()

	// Just wait for a moment before exiting to be
	// sure, all defers get called and the program
	// makes a clean exit.
	time.Sleep(150 * time.Millisecond)
}

// Create important folders if missing
func createDirectories() (err error) {
	// Create the slice of folder paths
	dirs := [...]string{
		settings.Settings.TmpPath,
		settings.Settings.PublicPath,
		settings.Settings.PagesPath,
		settings.Settings.TemplatesPath,
		settings.Settings.TranslationPath,
		settings.Settings.DataPath,
		settings.Settings.ScssPath,
	}

	// Create the directories
	for _, dir := range dirs {
		err = utils.MkDirIfNotExists(dir)
		if err != nil {
			return fmt.Errorf("failed to create directory: '%s': %v", dir, err)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package json

import "github.com/gopherjs/gopherjs/js"

func Marshal(v interface{}) ([]byte, error) {
	return MarshalIndent(v, "", "")
}

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
	s, err := MarshalIndentString(v, prefix, indent)
	return []byte(s), err
}

func MarshalString(v interface{}) (string, error) {
	return MarshalIndentString(v, "", "")
}

func MarshalIndentString(v interface{}, prefix, indent string) (string, error) {
	str := js.Global.Get("JSON").Call("stringify", js.InternalObject(jsonify).Invoke(js.InternalObject(v)), nil, indent)
	if len(prefix) > 0 {
		str = str.Call("replace", js.Global.Get("RegExp").New("\n", "g"), "\n"+prefix)
	}
	return str.String(), nil
}

const (
	boolKind       = 1
	intKind        = 2
	int8Kind       = 3
	int16Kind      = 4
	int32Kind      = 5
	int64Kind      = 6
	uintKind       = 7
	uint8Kind      = 8
	uint16Kind     = 9
	uint32Kind     = 10
	uint64Kind     = 11
	uintptrKind    = 12
	float32Kind    = 13
	float64Kind    = 14
	complex64Kind  = 15
	complex128Kind = 16
	arrayKind      = 17
	interfaceKind  = 20
	mapKind        = 21
	ptrKind        = 22
	sliceKind      = 23
	stringKind     = 24
	structKind     = 25
)

func jsonify(v *js.Object) *js.Object {
	t := v.Get("constructor")
	for t.Get("kind").Int() == ptrKind {
		if v.Get("$val") != t.Get("nil") {
			v = v.Call("$get")
			t = t.Get("elem")
		}
	}
	switch t.Get("kind").Int() {
	case boolKind, intKind, int8Kind, int16Kind, int32Kind, uintKind, uint8Kind, uint16Kind, uint32Kind, uintptrKind, float32Kind, float64Kind, int64Kind, uint64Kind, complex64Kind, complex128Kind, ptrKind, stringKind:
		return js.Global.Call("$externalize", v, t)
	case arrayKind, sliceKind:
		l := v.Get("$length").Int()
		a := js.Global.Get("Array").New(l)
		for i := 0; i < l; i++ {
			a.SetIndex(i, js.InternalObject(jsonify).Invoke(v.Get("$array").Index(i)))
		}
		return a
	case interfaceKind:
		return js.InternalObject(jsonify).Invoke(v.Get("$val"))
	case mapKind:
		m := js.Global.Get("Object").New()
		keys := js.Global.Get("Object").Call("keys", v)
		len := keys.Length()
		for i := 0; i < len; i++ {
			val := v.Get(keys.Index(i).String())
			m.Set(val.Get("k").String(), js.InternalObject(jsonify).Invoke(val.Get("v")))
		}
		return m
	case structKind:
		s := js.Global.Get("Object").New()
		todo := [][2]*js.Object{{v, t}}
		fieldsTodo := make(map[string]*js.Object)
		for _, val := range todo {
			v := val[0]
			t := val[1]
			fields := t.Get("fields")
			fieldsLen := fields.Length()
			for i := 0; i < fieldsLen; i++ {
				f := fields.Index(i)
				if f.Get("pkg").Length() > 0 {
					continue
				}
				fName := f.Get("prop").String()
				name := f.Get("name").String()
				anon := false
				if name == "" {
					name = fName // filter $x?
					anon = true
				}
				n, o := parseTag(getJSONTag(f.Get("tag")))
				if n == "-" || (o.Contains("omitempty") && isEmpty(v.Get(fName), f.Get("typ"))) {
					continue
				}
				jName := name
				if n != "" {
					jName = n
				}
				if _, ok := fieldsTodo[jName]; ok {
					fieldsTodo[jName] = nil
				} else if anon {
					todo = append(todo, [2]*js.Object{v.Get(fName), f.Get("typ")})
				} else if s.Get(jName) == js.Undefined {
					val := v.Get(fName)
					if o.Contains("string") && stringable(f.Get("typ")) {
						s := js.Global.Get("Object").New()
						s.Set("kind", stringKind)
						t := js.Global.Get("Object").New()
						t.Set("elem", s)
						t.Set("kind", ptrKind)
						v := js.Global.Get("Object").New()
						if f.Get("typ").Get("kind").Int() == stringKind {
							v.Set("$val", js.Global.Get("JSON").Call("stringify", val))
						} else {
							v.Set("$val", val.Call("toString"))
						}
						v.Set("constructor", t)
						v.Set("$get", js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} {
							return this.Get("$val")
						}))
						val = v

					} else if val.Get("constructor").Get("kind") == js.Undefined {
						t := js.Global.Get("Object").New()
						t.Set("elem", f.Get("typ"))
						t.Set("kind", ptrKind)
						v := js.Global.Get("Object").New()
						v.Set("$val", val)
						v.Set("constructor", t)
						v.Set("$get", js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} {
							return this.Get("$val")
						}))
						val = v
					} else if f.Get("typ").Get("kind").Int() == interfaceKind {
						val = val.Get("$val")
					}
					fieldsTodo[jName] = val
				}
			}
			for name, f := range fieldsTodo {
				if f != nil {
					s.Set(name, js.InternalObject(jsonify).Invoke(f))
					//delete(fieldsTodo, name)
				}
			}
		}
		return s
	}
	return js.Undefined
}

func isEmpty(v, t *js.Object) bool {
	switch t.Get("kind").Int() {
	case boolKind:
		return !v.Bool()
	case int8Kind, int16Kind, int32Kind, intKind, uint8Kind, uint16Kind, uint32Kind, uintKind:
		return v.Int() == 0
	case int64Kind, uint64Kind:
		return v.Int64() == 0
	case float32Kind, float64Kind:
		return v.Float() == 0
	case arrayKind, sliceKind, stringKind:
		return v.Length() == 0
	case ptrKind:
		return v == t.Get("nil")
	case interfaceKind:
		if v.Get("$val") == js.Undefined {
			return true
		}
		return isEmpty(v.Get("$val"), v.Get("constructor"))
	case mapKind:
		return js.Global.Get("Object").Call("keys", v).Length() == 0
	}
	return false
}

func stringable(t *js.Object) bool {
	switch t.Get("kind").Int() {
	case boolKind, int8Kind, int16Kind, int32Kind, intKind, uint8Kind, uint16Kind, uint32Kind, uintKind, int64Kind, uint64Kind, float32Kind, float64Kind, stringKind:
		return true
	}
	return false
}

func isMarshaler(t *js.Object) bool {
	methodNum := t.Get("methods").Length()
	for i := 0; i < methodNum; i++ {
		method := t.Get("methods").Index(i)
		if method.Get("name").String() == "MarshalJSON" {
			mt := method.Get("typ")
			return mt.Get("params").Length() == 0 && mt.Get("results").Length() == 2 && mt.Get("results").Index(0).Get("string").String() == "[]uint8" && mt.Get("results").Index(1).Get("string").String() == "error"
		}
	}
	return false
}
<commit_msg>Finished rewrite which now has prelim- support for anonymous/embedded fields<commit_after>package json

import "github.com/gopherjs/gopherjs/js"

func Marshal(v interface{}) ([]byte, error) {
	return MarshalIndent(v, "", "")
}

func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
	s, err := MarshalIndentString(v, prefix, indent)
	return []byte(s), err
}

func MarshalString(v interface{}) (string, error) {
	return MarshalIndentString(v, "", "")
}

func MarshalIndentString(v interface{}, prefix, indent string) (string, error) {
	str := js.Global.Get("JSON").Call("stringify", js.InternalObject(jsonify).Invoke(js.InternalObject(v)), nil, indent)
	if len(prefix) > 0 {
		str = str.Call("replace", js.Global.Get("RegExp").New("\n", "g"), "\n"+prefix)
	}
	return str.String(), nil
}

const (
	boolKind       = 1
	intKind        = 2
	int8Kind       = 3
	int16Kind      = 4
	int32Kind      = 5
	int64Kind      = 6
	uintKind       = 7
	uint8Kind      = 8
	uint16Kind     = 9
	uint32Kind     = 10
	uint64Kind     = 11
	uintptrKind    = 12
	float32Kind    = 13
	float64Kind    = 14
	complex64Kind  = 15
	complex128Kind = 16
	arrayKind      = 17
	interfaceKind  = 20
	mapKind        = 21
	ptrKind        = 22
	sliceKind      = 23
	stringKind     = 24
	structKind     = 25
)

func getInnerType(v, t *js.Object) (*js.Object, *js.Object) {
Loop:
	for {
		switch t.Get("kind").Int() {
		case ptrKind:
			if v.Get("$val") != t.Get("nil") {
				v = v.Call("$get")
				t = t.Get("elem")
			} else {
				break
			}
		case interfaceKind:
			t = v.Get("constructor")
			v = v.Get("$val")
		default:
			break Loop
		}
	}
	return v, t
}

func jsonify(v *js.Object) *js.Object {
	t := v.Get("constructor")
	v, t = getInnerType(v, t)
	switch t.Get("kind").Int() {
	case boolKind, intKind, int8Kind, int16Kind, int32Kind, uintKind, uint8Kind, uint16Kind, uint32Kind, uintptrKind, float32Kind, float64Kind, int64Kind, uint64Kind, complex64Kind, complex128Kind, ptrKind, stringKind:
		return js.Global.Call("$externalize", v, t)
	case arrayKind, sliceKind:
		l := v.Get("$length").Int()
		a := js.Global.Get("Array").New(l)
		for i := 0; i < l; i++ {
			a.SetIndex(i, js.InternalObject(jsonify).Invoke(v.Get("$array").Index(i)))
		}
		return a
	case mapKind:
		m := js.Global.Get("Object").New()
		keys := js.Global.Get("Object").Call("keys", v)
		len := keys.Length()
		for i := 0; i < len; i++ {
			val := v.Get(keys.Index(i).String())
			m.Set(val.Get("k").String(), js.InternalObject(jsonify).Invoke(val.Get("v")))
		}
		return m
	case structKind:
		s := js.Global.Get("Object").New()
		todo := [][2]*js.Object{{v, t}}
		fieldsTodo := make(map[string]*js.Object)
		for len(todo) > 0 {
			v := todo[0][0]
			t := todo[0][1]
			todo = todo[1:]
			fields := t.Get("fields")
			fieldsLen := fields.Length()
			for i := 0; i < fieldsLen; i++ {
				f := fields.Index(i)
				if f.Get("pkg").Length() > 0 {
					continue
				}
				fName := f.Get("prop").String()
				name := f.Get("name").String()
				anon := false
				if name == "" {
					name = fName // filter $x?
					anon = true
				}
				n, o := parseTag(getJSONTag(f.Get("tag")))
				if n == "-" || (o.Contains("omitempty") && isEmpty(v.Get(fName), f.Get("typ"))) {
					continue
				}
				jName := name
				if n != "" {
					jName = n
				}
				if _, ok := fieldsTodo[jName]; ok {
					fieldsTodo[jName] = nil
				} else if anon {
					v, t = getInnerType(v.Get(fName), f.Get("typ"))
					todo = append(todo, [2]*js.Object{v, t})
				} else if s.Get(jName) == js.Undefined {
					val := v.Get(fName)
					vt := f.Get("typ")
					val, vt = getInnerType(val, vt)
					if o.Contains("string") && stringable(vt) {
						s := js.Global.Get("Object").New()
						s.Set("kind", stringKind)
						t := js.Global.Get("Object").New()
						t.Set("elem", s)
						t.Set("kind", ptrKind)
						v := js.Global.Get("Object").New()
						if vt.Get("kind").Int() == stringKind {
							v.Set("$val", js.Global.Get("JSON").Call("stringify", val))
						} else {
							v.Set("$val", val.Call("toString"))
						}
						v.Set("constructor", t)
						v.Set("$get", js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} {
							return this.Get("$val")
						}))
						val = v

					} else if val.Get("constructor").Get("kind") == js.Undefined {
						t := js.Global.Get("Object").New()
						t.Set("elem", vt)
						t.Set("kind", ptrKind)
						v := js.Global.Get("Object").New()
						v.Set("$val", val)
						v.Set("constructor", t)
						v.Set("$get", js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} {
							return this.Get("$val")
						}))
						val = v
					}
					fieldsTodo[jName] = val
				}
			}
			for name, f := range fieldsTodo {
				if f != nil {
					s.Set(name, js.InternalObject(jsonify).Invoke(f))
					//delete(fieldsTodo, name)
				}
			}
		}
		return s
	}
	return js.Undefined
}

func isEmpty(v, t *js.Object) bool {
	switch t.Get("kind").Int() {
	case boolKind:
		return !v.Bool()
	case int8Kind, int16Kind, int32Kind, intKind, uint8Kind, uint16Kind, uint32Kind, uintKind:
		return v.Int() == 0
	case int64Kind, uint64Kind:
		return v.Int64() == 0
	case float32Kind, float64Kind:
		return v.Float() == 0
	case arrayKind, sliceKind, stringKind:
		return v.Length() == 0
	case ptrKind:
		return v == t.Get("nil")
	case interfaceKind:
		if v.Get("$val") == js.Undefined {
			return true
		}
		return isEmpty(v.Get("$val"), v.Get("constructor"))
	case mapKind:
		return js.Global.Get("Object").Call("keys", v).Length() == 0
	}
	return false
}

func stringable(t *js.Object) bool {
	switch t.Get("kind").Int() {
	case boolKind, int8Kind, int16Kind, int32Kind, intKind, uint8Kind, uint16Kind, uint32Kind, uintKind, int64Kind, uint64Kind, float32Kind, float64Kind, stringKind:
		return true
	}
	return false
}

func isMarshaler(t *js.Object) bool {
	methodNum := t.Get("methods").Length()
	for i := 0; i < methodNum; i++ {
		method := t.Get("methods").Index(i)
		if method.Get("name").String() == "MarshalJSON" {
			mt := method.Get("typ")
			return mt.Get("params").Length() == 0 && mt.Get("results").Length() == 2 && mt.Get("results").Index(0).Get("string").String() == "[]uint8" && mt.Get("results").Index(1).Get("string").String() == "error"
		}
	}
	return false
}
<|endoftext|>


<commit_before>package drone

//go:generate mockery -all
//go:generate mv mocks/Client.go mocks/client.go

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"

	"golang.org/x/oauth2"
)

const (
	pathSelf    = "%s/api/user"
	pathFeed    = "%s/api/user/feed"
	pathRepos   = "%s/api/user/repos"
	pathRepo    = "%s/api/repos/%s/%s"
	pathEncrypt = "%s/api/repos/%s/%s/encrypt"
	pathBuilds  = "%s/api/repos/%s/%s/builds"
	pathBuild   = "%s/api/repos/%s/%s/builds/%v"
	pathJob     = "%s/api/repos/%s/%s/builds/%d/%d"
	pathLog     = "%s/api/repos/%s/%s/logs/%d/%d"
	pathKey     = "%s/api/repos/%s/%s/key"
	pathNodes   = "%s/api/nodes"
	pathNode    = "%s/api/nodes/%d"
	pathUsers   = "%s/api/users"
	pathUser    = "%s/api/users/%s"
)

type client struct {
	client *http.Client
	base   string // base url
}

// NewClient returns a client at the specified url.
func NewClient(uri string) Client {
	return &client{http.DefaultClient, uri}
}

// NewClientToken returns a client at the specified url that
// authenticates all outbound requests with the given token.
func NewClientToken(uri, token string) Client {
	config := new(oauth2.Config)
	auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
	return &client{auther, uri}
}

// NewClientTokenTLS returns a client at the specified url that
// authenticates all outbound requests with the given token and
// tls.Config if provided.
func NewClientTokenTLS(uri, token string, c *tls.Config) Client {
	config := new(oauth2.Config)
	auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
	if c != nil {
		auther.Transport = &http.Transport{TLSClientConfig: c}
	}
	return &client{auther, uri}
}

// SetClient sets the default http client. This should be
// used in conjunction with golang.org/x/oauth2 to
// authenticate requests to the Drone server.
func (c *client) SetClient(client *http.Client) {
	c.client = client
}

// Self returns the currently authenticated user.
func (c *client) Self() (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathSelf, c.base)
	err := c.get(uri, out)
	return out, err
}

// User returns a user by login.
func (c *client) User(login string) (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathUser, c.base, login)
	err := c.get(uri, out)
	return out, err
}

// UserList returns a list of all registered users.
func (c *client) UserList() ([]*User, error) {
	var out []*User
	uri := fmt.Sprintf(pathUsers, c.base)
	err := c.get(uri, &out)
	return out, err
}

// UserPost creates a new user account.
func (c *client) UserPost(in *User) (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathUsers, c.base)
	err := c.post(uri, in, out)
	return out, err
}

// UserPatch updates a user account.
func (c *client) UserPatch(in *User) (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathUser, c.base, in.Login)
	err := c.patch(uri, in, out)
	return out, err
}

// UserDel deletes a user account.
func (c *client) UserDel(login string) error {
	uri := fmt.Sprintf(pathUser, c.base, login)
	err := c.delete(uri)
	return err
}

// UserFeed returns the user's activity feed.
func (c *client) UserFeed() ([]*Activity, error) {
	var out []*Activity
	uri := fmt.Sprintf(pathFeed, c.base)
	err := c.get(uri, &out)
	return out, err
}

// Repo returns a repository by name.
func (c *client) Repo(owner string, name string) (*Repo, error) {
	out := new(Repo)
	uri := fmt.Sprintf(pathRepo, c.base, owner, name)
	err := c.get(uri, out)
	return out, err
}

// RepoList returns a list of all repositories to which
// the user has explicit access in the host system.
func (c *client) RepoList() ([]*Repo, error) {
	var out []*Repo
	uri := fmt.Sprintf(pathRepos, c.base)
	err := c.get(uri, &out)
	return out, err
}

// RepoPost activates a repository.
func (c *client) RepoPost(owner string, name string) (*Repo, error) {
	out := new(Repo)
	uri := fmt.Sprintf(pathRepo, c.base, owner, name)
	err := c.post(uri, nil, out)
	return out, err
}

// RepoPatch updates a repository.
func (c *client) RepoPatch(in *Repo) (*Repo, error) {
	out := new(Repo)
	uri := fmt.Sprintf(pathRepo, c.base, in.Owner, in.Name)
	err := c.patch(uri, in, out)
	return out, err
}

// RepoDel deletes a repository.
func (c *client) RepoDel(owner, name string) error {
	uri := fmt.Sprintf(pathRepo, c.base, owner, name)
	err := c.delete(uri)
	return err
}

// RepoKey returns a repository public key.
func (c *client) RepoKey(owner, name string) (*Key, error) {
	out := new(Key)
	uri := fmt.Sprintf(pathKey, c.base, owner, name)
	rc, err := c.stream(uri, "GET", nil, nil)
	if err != nil {
		return nil, err
	}
	defer rc.Close()
	raw, _ := ioutil.ReadAll(rc)
	out.Public = string(raw)
	return out, err
}

// Build returns a repository build by number.
func (c *client) Build(owner, name string, num int) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
	err := c.get(uri, out)
	return out, err
}

// Build returns the latest repository build by branch.
func (c *client) BuildLast(owner, name, branch string) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild, c.base, owner, name, "latest")
	if len(branch) != 0 {
		uri += "?branch=" + branch
	}
	err := c.get(uri, out)
	return out, err
}

// BuildList returns a list of recent builds for the
// the specified repository.
func (c *client) BuildList(owner, name string) ([]*Build, error) {
	var out []*Build
	uri := fmt.Sprintf(pathBuilds, c.base, owner, name)
	err := c.get(uri, &out)
	return out, err
}

// BuildStart re-starts a stopped build.
func (c *client) BuildStart(owner, name string, num int) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
	err := c.post(uri, nil, out)
	return out, err
}

// BuildStop cancels the running job.
func (c *client) BuildStop(owner, name string, num, job int) error {
	uri := fmt.Sprintf(pathJob, c.base, owner, name, num, job)
	err := c.delete(uri)
	return err
}

// BuildFork re-starts a stopped build with a new build number,
// preserving the prior history.
func (c *client) BuildFork(owner, name string, num int) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild+"?fork=true", c.base, owner, name, num)
	err := c.post(uri, nil, out)
	return out, err
}

// BuildLogs returns the build logs for the specified job.
func (c *client) BuildLogs(owner, name string, num, job int) (io.ReadCloser, error) {
	uri := fmt.Sprintf(pathLog, c.base, owner, name, num, job)
	return c.stream(uri, "GET", nil, nil)
}

// Node returns a node by id.
func (c *client) Node(id int64) (*Node, error) {
	out := new(Node)
	uri := fmt.Sprintf(pathNode, c.base, id)
	err := c.get(uri, out)
	return out, err
}

// NodeList returns a list of all registered worker nodes.
func (c *client) NodeList() ([]*Node, error) {
	var out []*Node
	uri := fmt.Sprintf(pathNodes, c.base)
	err := c.get(uri, &out)
	return out, err
}

// NodePost registers a new worker node.
func (c *client) NodePost(in *Node) (*Node, error) {
	out := new(Node)
	uri := fmt.Sprintf(pathNodes, c.base)
	err := c.post(uri, in, out)
	return out, err
}

// NodeDel deletes a worker node.
func (c *client) NodeDel(id int64) error {
	uri := fmt.Sprintf(pathNode, c.base, id)
	err := c.delete(uri)
	return err
}

//
// http request helper functions
//

// helper function for making an http GET request.
func (c *client) get(rawurl string, out interface{}) error {
	return c.do(rawurl, "GET", nil, out)
}

// helper function for making an http POST request.
func (c *client) post(rawurl string, in, out interface{}) error {
	return c.do(rawurl, "POST", in, out)
}

// helper function for making an http PUT request.
func (c *client) put(rawurl string, in, out interface{}) error {
	return c.do(rawurl, "PUT", in, out)
}

// helper function for making an http PATCH request.
func (c *client) patch(rawurl string, in, out interface{}) error {
	return c.do(rawurl, "PATCH", in, out)
}

// helper function for making an http DELETE request.
func (c *client) delete(rawurl string) error {
	return c.do(rawurl, "DELETE", nil, nil)
}

// helper function to make an http request
func (c *client) do(rawurl, method string, in, out interface{}) error {
	// executes the http request and returns the body as
	// and io.ReadCloser
	body, err := c.stream(rawurl, method, in, out)
	if err != nil {
		return err
	}
	defer body.Close()

	// if a json response is expected, parse and return
	// the json response.
	if out != nil {
		return json.NewDecoder(body).Decode(out)
	}
	return nil
}

// helper function to stream an http request
func (c *client) stream(rawurl, method string, in, out interface{}) (io.ReadCloser, error) {
	uri, err := url.Parse(rawurl)
	if err != nil {
		return nil, err
	}

	// if we are posting or putting data, we need to
	// write it to the body of the request.
	var buf io.ReadWriter
	if in != nil {
		buf = new(bytes.Buffer)
		err := json.NewEncoder(buf).Encode(in)
		if err != nil {
			return nil, err
		}
	}

	// creates a new http request to bitbucket.
	req, err := http.NewRequest(method, uri.String(), buf)
	if err != nil {
		return nil, err
	}
	if in != nil {
		req.Header.Set("Content-Type", "application/json")
	}

	resp, err := c.client.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode > http.StatusPartialContent {
		defer resp.Body.Close()
		out, _ := ioutil.ReadAll(resp.Body)
		return nil, fmt.Errorf(string(out))
	}
	return resp.Body, nil
}
<commit_msg>fixing oauth2 tlsconfig issue<commit_after>package drone

//go:generate mockery -all
//go:generate mv mocks/Client.go mocks/client.go

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"

	"golang.org/x/oauth2"
)

const (
	pathSelf    = "%s/api/user"
	pathFeed    = "%s/api/user/feed"
	pathRepos   = "%s/api/user/repos"
	pathRepo    = "%s/api/repos/%s/%s"
	pathEncrypt = "%s/api/repos/%s/%s/encrypt"
	pathBuilds  = "%s/api/repos/%s/%s/builds"
	pathBuild   = "%s/api/repos/%s/%s/builds/%v"
	pathJob     = "%s/api/repos/%s/%s/builds/%d/%d"
	pathLog     = "%s/api/repos/%s/%s/logs/%d/%d"
	pathKey     = "%s/api/repos/%s/%s/key"
	pathNodes   = "%s/api/nodes"
	pathNode    = "%s/api/nodes/%d"
	pathUsers   = "%s/api/users"
	pathUser    = "%s/api/users/%s"
)

type client struct {
	client *http.Client
	base   string // base url
}

// NewClient returns a client at the specified url.
func NewClient(uri string) Client {
	return &client{http.DefaultClient, uri}
}

// NewClientToken returns a client at the specified url that
// authenticates all outbound requests with the given token.
func NewClientToken(uri, token string) Client {
	config := new(oauth2.Config)
	auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
	return &client{auther, uri}
}

// NewClientTokenTLS returns a client at the specified url that
// authenticates all outbound requests with the given token and
// tls.Config if provided.
func NewClientTokenTLS(uri, token string, c *tls.Config) Client {
	config := new(oauth2.Config)
	auther := config.Client(oauth2.NoContext, &oauth2.Token{AccessToken: token})
	if c != nil {
		auther.Transport.(*oauth2.Transport).Base = &http.Transport{TLSClientConfig: c}
	}
	return &client{auther, uri}
}

// SetClient sets the default http client. This should be
// used in conjunction with golang.org/x/oauth2 to
// authenticate requests to the Drone server.
func (c *client) SetClient(client *http.Client) {
	c.client = client
}

// Self returns the currently authenticated user.
func (c *client) Self() (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathSelf, c.base)
	err := c.get(uri, out)
	return out, err
}

// User returns a user by login.
func (c *client) User(login string) (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathUser, c.base, login)
	err := c.get(uri, out)
	return out, err
}

// UserList returns a list of all registered users.
func (c *client) UserList() ([]*User, error) {
	var out []*User
	uri := fmt.Sprintf(pathUsers, c.base)
	err := c.get(uri, &out)
	return out, err
}

// UserPost creates a new user account.
func (c *client) UserPost(in *User) (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathUsers, c.base)
	err := c.post(uri, in, out)
	return out, err
}

// UserPatch updates a user account.
func (c *client) UserPatch(in *User) (*User, error) {
	out := new(User)
	uri := fmt.Sprintf(pathUser, c.base, in.Login)
	err := c.patch(uri, in, out)
	return out, err
}

// UserDel deletes a user account.
func (c *client) UserDel(login string) error {
	uri := fmt.Sprintf(pathUser, c.base, login)
	err := c.delete(uri)
	return err
}

// UserFeed returns the user's activity feed.
func (c *client) UserFeed() ([]*Activity, error) {
	var out []*Activity
	uri := fmt.Sprintf(pathFeed, c.base)
	err := c.get(uri, &out)
	return out, err
}

// Repo returns a repository by name.
func (c *client) Repo(owner string, name string) (*Repo, error) {
	out := new(Repo)
	uri := fmt.Sprintf(pathRepo, c.base, owner, name)
	err := c.get(uri, out)
	return out, err
}

// RepoList returns a list of all repositories to which
// the user has explicit access in the host system.
func (c *client) RepoList() ([]*Repo, error) {
	var out []*Repo
	uri := fmt.Sprintf(pathRepos, c.base)
	err := c.get(uri, &out)
	return out, err
}

// RepoPost activates a repository.
func (c *client) RepoPost(owner string, name string) (*Repo, error) {
	out := new(Repo)
	uri := fmt.Sprintf(pathRepo, c.base, owner, name)
	err := c.post(uri, nil, out)
	return out, err
}

// RepoPatch updates a repository.
func (c *client) RepoPatch(in *Repo) (*Repo, error) {
	out := new(Repo)
	uri := fmt.Sprintf(pathRepo, c.base, in.Owner, in.Name)
	err := c.patch(uri, in, out)
	return out, err
}

// RepoDel deletes a repository.
func (c *client) RepoDel(owner, name string) error {
	uri := fmt.Sprintf(pathRepo, c.base, owner, name)
	err := c.delete(uri)
	return err
}

// RepoKey returns a repository public key.
func (c *client) RepoKey(owner, name string) (*Key, error) {
	out := new(Key)
	uri := fmt.Sprintf(pathKey, c.base, owner, name)
	rc, err := c.stream(uri, "GET", nil, nil)
	if err != nil {
		return nil, err
	}
	defer rc.Close()
	raw, _ := ioutil.ReadAll(rc)
	out.Public = string(raw)
	return out, err
}

// Build returns a repository build by number.
func (c *client) Build(owner, name string, num int) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
	err := c.get(uri, out)
	return out, err
}

// Build returns the latest repository build by branch.
func (c *client) BuildLast(owner, name, branch string) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild, c.base, owner, name, "latest")
	if len(branch) != 0 {
		uri += "?branch=" + branch
	}
	err := c.get(uri, out)
	return out, err
}

// BuildList returns a list of recent builds for the
// the specified repository.
func (c *client) BuildList(owner, name string) ([]*Build, error) {
	var out []*Build
	uri := fmt.Sprintf(pathBuilds, c.base, owner, name)
	err := c.get(uri, &out)
	return out, err
}

// BuildStart re-starts a stopped build.
func (c *client) BuildStart(owner, name string, num int) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild, c.base, owner, name, num)
	err := c.post(uri, nil, out)
	return out, err
}

// BuildStop cancels the running job.
func (c *client) BuildStop(owner, name string, num, job int) error {
	uri := fmt.Sprintf(pathJob, c.base, owner, name, num, job)
	err := c.delete(uri)
	return err
}

// BuildFork re-starts a stopped build with a new build number,
// preserving the prior history.
func (c *client) BuildFork(owner, name string, num int) (*Build, error) {
	out := new(Build)
	uri := fmt.Sprintf(pathBuild+"?fork=true", c.base, owner, name, num)
	err := c.post(uri, nil, out)
	return out, err
}

// BuildLogs returns the build logs for the specified job.
func (c *client) BuildLogs(owner, name string, num, job int) (io.ReadCloser, error) {
	uri := fmt.Sprintf(pathLog, c.base, owner, name, num, job)
	return c.stream(uri, "GET", nil, nil)
}

// Node returns a node by id.
func (c *client) Node(id int64) (*Node, error) {
	out := new(Node)
	uri := fmt.Sprintf(pathNode, c.base, id)
	err := c.get(uri, out)
	return out, err
}

// NodeList returns a list of all registered worker nodes.
func (c *client) NodeList() ([]*Node, error) {
	var out []*Node
	uri := fmt.Sprintf(pathNodes, c.base)
	err := c.get(uri, &out)
	return out, err
}

// NodePost registers a new worker node.
func (c *client) NodePost(in *Node) (*Node, error) {
	out := new(Node)
	uri := fmt.Sprintf(pathNodes, c.base)
	err := c.post(uri, in, out)
	return out, err
}

// NodeDel deletes a worker node.
func (c *client) NodeDel(id int64) error {
	uri := fmt.Sprintf(pathNode, c.base, id)
	err := c.delete(uri)
	return err
}

//
// http request helper functions
//

// helper function for making an http GET request.
func (c *client) get(rawurl string, out interface{}) error {
	return c.do(rawurl, "GET", nil, out)
}

// helper function for making an http POST request.
func (c *client) post(rawurl string, in, out interface{}) error {
	return c.do(rawurl, "POST", in, out)
}

// helper function for making an http PUT request.
func (c *client) put(rawurl string, in, out interface{}) error {
	return c.do(rawurl, "PUT", in, out)
}

// helper function for making an http PATCH request.
func (c *client) patch(rawurl string, in, out interface{}) error {
	return c.do(rawurl, "PATCH", in, out)
}

// helper function for making an http DELETE request.
func (c *client) delete(rawurl string) error {
	return c.do(rawurl, "DELETE", nil, nil)
}

// helper function to make an http request
func (c *client) do(rawurl, method string, in, out interface{}) error {
	// executes the http request and returns the body as
	// and io.ReadCloser
	body, err := c.stream(rawurl, method, in, out)
	if err != nil {
		return err
	}
	defer body.Close()

	// if a json response is expected, parse and return
	// the json response.
	if out != nil {
		return json.NewDecoder(body).Decode(out)
	}
	return nil
}

// helper function to stream an http request
func (c *client) stream(rawurl, method string, in, out interface{}) (io.ReadCloser, error) {
	uri, err := url.Parse(rawurl)
	if err != nil {
		return nil, err
	}

	// if we are posting or putting data, we need to
	// write it to the body of the request.
	var buf io.ReadWriter
	if in != nil {
		buf = new(bytes.Buffer)
		err := json.NewEncoder(buf).Encode(in)
		if err != nil {
			return nil, err
		}
	}

	// creates a new http request to bitbucket.
	req, err := http.NewRequest(method, uri.String(), buf)
	if err != nil {
		return nil, err
	}
	if in != nil {
		req.Header.Set("Content-Type", "application/json")
	}

	resp, err := c.client.Do(req)
	if err != nil {
		return nil, err
	}
	if resp.StatusCode > http.StatusPartialContent {
		defer resp.Body.Close()
		out, _ := ioutil.ReadAll(resp.Body)
		return nil, fmt.Errorf(string(out))
	}
	return resp.Body, nil
}
<|endoftext|>


<commit_before>/*
© Copyright IBM Corporation 2017

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.
*/

// chkmqhealthy checks that MQ is healthy, by checking the output of the "dspmq" command
package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/ibm-messaging/mq-container/internal/name"
)

func queueManagerHealthy() (bool, error) {
	name, err := name.GetQueueManagerName()
	if err != nil {
		return false, err
	}
	// Specify the queue manager name, just in case someone's created a second queue manager
	cmd := exec.Command("dspmq", "-n", "-m", name)
	// Run the command and wait for completion
	out, err := cmd.CombinedOutput()
	if err != nil {
		fmt.Println(err)
		return false, err
	}
	fmt.Println(out)
	if !strings.Contains(string(out), "(RUNNING)") {
		return false, nil
	}
	return true, nil
}

func main() {
	healthy, err := queueManagerHealthy()
	if err != nil {
		os.Exit(2)
	}
	if !healthy {
		os.Exit(1)
	}
	os.Exit(0)
}
<commit_msg>force string output in chkmqhealthy (#174)<commit_after>/*
© Copyright IBM Corporation 2017

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.
*/

// chkmqhealthy checks that MQ is healthy, by checking the output of the "dspmq" command
package main

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"github.com/ibm-messaging/mq-container/internal/name"
)

func queueManagerHealthy() (bool, error) {
	name, err := name.GetQueueManagerName()
	if err != nil {
		return false, err
	}
	// Specify the queue manager name, just in case someone's created a second queue manager
	cmd := exec.Command("dspmq", "-n", "-m", name)
	// Run the command and wait for completion
	out, err := cmd.CombinedOutput()
	if err != nil {
		fmt.Println(err)
		return false, err
	}
	fmt.Printf("%s", out)
	if !strings.Contains(string(out), "(RUNNING)") {
		return false, nil
	}
	return true, nil
}

func main() {
	healthy, err := queueManagerHealthy()
	if err != nil {
		os.Exit(2)
	}
	if !healthy {
		os.Exit(1)
	}
	os.Exit(0)
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2017, Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

// Package queue implements a double-ended queue (aka "deque") on top
// of a slice. All operations are (amortized) constant time.
// Benchmarks compare favorably to container/list as well as to Go's
// channels.
// Not safe for concurrent use.
package queue

import (
	"bytes"
	"fmt"
)

// Queue represents a double-ended queue.
// The zero value for Queue is an empty queue ready to use.
type Queue struct {
	// PushBack writes to rep[back] and then increments
	// back; PushFront decrements front and then writes
	// to rep[front]; len(rep) must be a power of two.
	rep    []interface{}
	front  int
	back   int
	length int
}

// New returns an initialized empty queue.
func New() *Queue {
	return new(Queue).Init()
}

// Init initializes or clears queue q.
func (q *Queue) Init() *Queue {
	q.rep = make([]interface{}, 1)
	q.front, q.back, q.length = 0, 0, 0
	return q
}

// lazyInit lazily initializes a zero Queue value.
//
// I am mostly doing this because container/list does the same thing.
// Personally I think it's a little wasteful because every single
// PushFront/PushBack is going to pay the overhead of calling this.
// But that's the price for making zero values useful immediately.
func (q *Queue) lazyInit() {
	if q.rep == nil {
		q.Init()
	}
}

// Len returns the number of elements of queue q.
func (q *Queue) Len() int {
	return q.length
}

// empty returns true if the queue q has no elements.
func (q *Queue) empty() bool {
	return q.length == 0
}

// full returns true if the queue q is at capacity.
func (q *Queue) full() bool {
	return q.length == len(q.rep)
}

// sparse returns true if the queue q has excess capacity.
func (q *Queue) sparse() bool {
	return 1 < q.length && q.length < len(q.rep)/4
}

// resize adjusts the size of queue q's underlying slice.
func (q *Queue) resize(size int) {
	adjusted := make([]interface{}, size)
	if q.front < q.back {
		// rep not "wrapped" around, one copy suffices
		copy(adjusted, q.rep[q.front:q.back])
	} else {
		// rep is "wrapped" around, need two copies
		n := copy(adjusted, q.rep[q.front:])
		copy(adjusted[n:], q.rep[:q.back])
	}
	q.rep = adjusted
	q.front = 0
	q.back = q.length
}

// lazyGrow grows the underlying slice if necessary.
func (q *Queue) lazyGrow() {
	if q.full() {
		q.resize(len(q.rep) * 2)
	}
}

// lazyShrink shrinks the underlying slice if advisable.
func (q *Queue) lazyShrink() {
	if q.sparse() {
		q.resize(len(q.rep) / 2)
	}
}

// String returns a string representation of queue q formatted
// from front to back.
func (q *Queue) String() string {
	var result bytes.Buffer
	result.WriteByte('[')
	j := q.front
	for i := 0; i < q.length; i++ {
		result.WriteString(fmt.Sprintf("%v", q.rep[j]))
		if i < q.length-1 {
			result.WriteByte(' ')
		}
		j = q.inc(j)
	}
	result.WriteByte(']')
	return result.String()
}

// inc returns the next integer position wrapping around queue q.
func (q *Queue) inc(i int) int {
	return (i + 1) & (len(q.rep) - 1) // requires l = 2^n
}

// dec returns the previous integer position wrapping around queue q.
func (q *Queue) dec(i int) int {
	return (i - 1) & (len(q.rep) - 1) // requires l = 2^n
}

// Front returns the first element of queue q or nil.
func (q *Queue) Front() interface{} {
	if q.empty() {
		return nil
	}
	return q.rep[q.front]
}

// Back returns the last element of queue q or nil.
func (q *Queue) Back() interface{} {
	if q.empty() {
		return nil
	}
	return q.rep[q.dec(q.back)]
}

// PushFront inserts a new value v at the front of queue q.
func (q *Queue) PushFront(v interface{}) {
	q.lazyInit()
	q.lazyGrow()
	q.front = q.dec(q.front)
	q.rep[q.front] = v
	q.length++
}

// PushBack inserts a new value v at the back of queue q.
func (q *Queue) PushBack(v interface{}) {
	q.lazyInit()
	q.lazyGrow()
	q.rep[q.back] = v
	q.back = q.inc(q.back)
	q.length++
}

// PopFront removes and returns the first element of queue q or nil.
func (q *Queue) PopFront() interface{} {
	if q.empty() {
		return nil
	}
	v := q.rep[q.front]
	q.rep[q.front] = nil // be nice to GC
	q.front = q.inc(q.front)
	q.length--
	q.lazyShrink()
	return v
}

// PopBack removes and returns the last element of queue q or nil.
func (q *Queue) PopBack() interface{} {
	if q.empty() {
		return nil
	}
	q.back = q.dec(q.back)
	v := q.rep[q.back]
	q.rep[q.back] = nil // be nice to GC
	q.length--
	q.lazyShrink()
	return v
}
<commit_msg>No more q.empty() in Front and Back.<commit_after>// Copyright (c) 2013-2017, Peter H. Froehlich. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

// Package queue implements a double-ended queue (aka "deque") on top of a
// slice. All operations are (amortized) constant time. Benchmarks compare
// favorably to container/list as well as to Go's channels. Not safe for
// concurrent use.
package queue

import (
	"bytes"
	"fmt"
)

// Queue represents a double-ended queue.
// The zero value is an empty queue ready to use.
type Queue struct {
	// PushBack writes to rep[back] then increments back; PushFront
	// decrements front then writes to rep[front]; len(rep) is a power
	// of two; unused slots are nil and not garbage.
	rep    []interface{}
	front  int
	back   int
	length int
}

// New returns an initialized empty queue.
func New() *Queue {
	return new(Queue).Init()
}

// Init initializes or clears queue q.
func (q *Queue) Init() *Queue {
	q.rep = make([]interface{}, 1)
	q.front, q.back, q.length = 0, 0, 0
	return q
}

// lazyInit lazily initializes a zero Queue value.
//
// I am mostly doing this because container/list does the same thing.
// Personally I think it's a little wasteful because every single
// PushFront/PushBack is going to pay the overhead of calling this.
// But that's the price for making zero values useful immediately.
func (q *Queue) lazyInit() {
	if q.rep == nil {
		q.Init()
	}
}

// Len returns the number of elements of queue q.
func (q *Queue) Len() int {
	return q.length
}

// empty returns true if the queue q has no elements.
func (q *Queue) empty() bool {
	return q.length == 0
}

// full returns true if the queue q is at capacity.
func (q *Queue) full() bool {
	return q.length == len(q.rep)
}

// sparse returns true if the queue q has excess capacity.
func (q *Queue) sparse() bool {
	return 1 < q.length && q.length < len(q.rep)/4
}

// resize adjusts the size of queue q's underlying slice.
func (q *Queue) resize(size int) {
	adjusted := make([]interface{}, size)
	if q.front < q.back {
		// rep not "wrapped" around, one copy suffices
		copy(adjusted, q.rep[q.front:q.back])
	} else {
		// rep is "wrapped" around, need two copies
		n := copy(adjusted, q.rep[q.front:])
		copy(adjusted[n:], q.rep[:q.back])
	}
	q.rep = adjusted
	q.front = 0
	q.back = q.length
}

// lazyGrow grows the underlying slice if necessary.
func (q *Queue) lazyGrow() {
	if q.full() {
		q.resize(len(q.rep) * 2)
	}
}

// lazyShrink shrinks the underlying slice if advisable.
func (q *Queue) lazyShrink() {
	if q.sparse() {
		q.resize(len(q.rep) / 2)
	}
}

// String returns a string representation of queue q formatted
// from front to back.
func (q *Queue) String() string {
	var result bytes.Buffer
	result.WriteByte('[')
	j := q.front
	for i := 0; i < q.length; i++ {
		result.WriteString(fmt.Sprintf("%v", q.rep[j]))
		if i < q.length-1 {
			result.WriteByte(' ')
		}
		j = q.inc(j)
	}
	result.WriteByte(']')
	return result.String()
}

// inc returns the next integer position wrapping around queue q.
func (q *Queue) inc(i int) int {
	return (i + 1) & (len(q.rep) - 1) // requires l = 2^n
}

// dec returns the previous integer position wrapping around queue q.
func (q *Queue) dec(i int) int {
	return (i - 1) & (len(q.rep) - 1) // requires l = 2^n
}

// Front returns the first element of queue q or nil.
func (q *Queue) Front() interface{} {
	// no need to check q.empty(), unused slots are nil
	return q.rep[q.front]
}

// Back returns the last element of queue q or nil.
func (q *Queue) Back() interface{} {
	// no need to check q.empty(), unused slots are nil
	return q.rep[q.dec(q.back)]
}

// PushFront inserts a new value v at the front of queue q.
func (q *Queue) PushFront(v interface{}) {
	q.lazyInit()
	q.lazyGrow()
	q.front = q.dec(q.front)
	q.rep[q.front] = v
	q.length++
}

// PushBack inserts a new value v at the back of queue q.
func (q *Queue) PushBack(v interface{}) {
	q.lazyInit()
	q.lazyGrow()
	q.rep[q.back] = v
	q.back = q.inc(q.back)
	q.length++
}

// PopFront removes and returns the first element of queue q or nil.
func (q *Queue) PopFront() interface{} {
	if q.empty() {
		return nil
	}
	v := q.rep[q.front]
	q.rep[q.front] = nil // unused slots must be nil
	q.front = q.inc(q.front)
	q.length--
	q.lazyShrink()
	return v
}

// PopBack removes and returns the last element of queue q or nil.
func (q *Queue) PopBack() interface{} {
	if q.empty() {
		return nil
	}
	q.back = q.dec(q.back)
	v := q.rep[q.back]
	q.rep[q.back] = nil // unused slots must be nil
	q.length--
	q.lazyShrink()
	return v
}
<|endoftext|>


<commit_before>package goinsta

type accountResp struct {
	Status  string  `json:"status"`
	Account Account `json:"logged_in_user"`
}

// Account is personal account object
type Account struct {
	// Activity is recent activity
	//Activity *Activity
	// Tray is your disponible friend's stories
	//Tray *Tray

	inst *Instagram

	CanSeeOrganicInsights      bool    `json:"can_see_organic_insights"`
	ShowInsightsTerms          bool    `json:"show_insights_terms"`
	IsBusiness                 bool    `json:"is_business"`
	Nametag                    Nametag `json:"nametag"`
	ID                         int64   `json:"pk"`
	Username                   string  `json:"username"`
	FullName                   string  `json:"full_name"`
	HasAnonymousProfilePicture bool    `json:"has_anonymous_profile_picture"`
	IsPrivate                  bool    `json:"is_private"`
	IsVerified                 bool    `json:"is_verified"`
	ProfilePicURL              string  `json:"profile_pic_url"`
	ProfilePicID               string  `json:"profile_pic_id"`
	AllowedCommenterType       string  `json:"allowed_commenter_type"`
	ReelAutoArchive            string  `json:"reel_auto_archive"`
	AllowContactsSync          bool    `json:"allow_contacts_sync"`
	PhoneNumber                string  `json:"phone_number"`
}

// NewAccount creates new account structure
func NewAccount(inst *Instagram) *Account {
	account := &Account{
		inst: inst,
	}
	return account
}
<commit_msg>Deleted NewAccount (uneeded)<commit_after>package goinsta

type accountResp struct {
	Status  string  `json:"status"`
	Account Account `json:"logged_in_user"`
}

// Account is personal account object
type Account struct {
	// Activity is recent activity
	//Activity *Activity
	// Tray is your disponible friend's stories
	//Tray *Tray

	inst *Instagram

	CanSeeOrganicInsights      bool    `json:"can_see_organic_insights"`
	ShowInsightsTerms          bool    `json:"show_insights_terms"`
	IsBusiness                 bool    `json:"is_business"`
	Nametag                    Nametag `json:"nametag"`
	ID                         int64   `json:"pk"`
	Username                   string  `json:"username"`
	FullName                   string  `json:"full_name"`
	HasAnonymousProfilePicture bool    `json:"has_anonymous_profile_picture"`
	IsPrivate                  bool    `json:"is_private"`
	IsVerified                 bool    `json:"is_verified"`
	ProfilePicURL              string  `json:"profile_pic_url"`
	ProfilePicID               string  `json:"profile_pic_id"`
	AllowedCommenterType       string  `json:"allowed_commenter_type"`
	ReelAutoArchive            string  `json:"reel_auto_archive"`
	AllowContactsSync          bool    `json:"allow_contacts_sync"`
	PhoneNumber                string  `json:"phone_number"`
}
<|endoftext|>


<commit_before>package tempFluc

import (
	"math"
)
import (
	"../bzone"
	"../solve"
	"../tempAll"
	vec "../vector"
)

func AbsErrorMu_h(env *tempAll.Environment, variables []string) solve.Diffable {
	F := func(v vec.Vector) (float64, error) {
		env.Set(v, variables)
		L := env.PointsPerSide
		lhs := 0.5 / (env.T0 + env.Tz)
		rhs := bzone.Avg(L, 2, tempAll.WrapFunc(env, innerMu_h))
		return lhs - rhs, nil
	}
	h := 1e-6
	epsabs := 1e-4
	return solve.SimpleDiffable(F, len(variables), h, epsabs)
}

func innerMu_h(env *tempAll.Environment, k vec.Vector) float64 {
	sxy := math.Sin(k[0]) - math.Sin(k[1])
	numer := sxy * sxy * math.Tanh(env.Beta*env.Xi_h(k)/2.0)
	denom := env.Mu_b + 2.0*env.Xi_h(k)
	return numer / denom
}
<commit_msg>tempFluc systemMu_h returns to tempPair form when T > T_p<commit_after>package tempFluc

import (
	"math"
)
import (
	"../bzone"
	"../solve"
	"../tempAll"
	"../tempPair"
	vec "../vector"
)

func AbsErrorMu_h(env *tempAll.Environment, variables []string) solve.Diffable {
	F := func(v vec.Vector) (float64, error) {
		env.Set(v, variables)
		if -env.Mu_b > -2.0*env.Mu_h {
			// when |Mu_b| is this large, no longer have pairs
			return env.X - tempPair.X1(env), nil
		}
		L := env.PointsPerSide
		lhs := 0.5 / (env.T0 + env.Tz)
		rhs := bzone.Avg(L, 2, tempAll.WrapFunc(env, innerMu_h))
		return lhs - rhs, nil
	}
	h := 1e-6
	epsabs := 1e-4
	return solve.SimpleDiffable(F, len(variables), h, epsabs)
}

func innerMu_h(env *tempAll.Environment, k vec.Vector) float64 {
	sxy := math.Sin(k[0]) - math.Sin(k[1])
	numer := sxy * sxy * math.Tanh(env.Beta*env.Xi_h(k)/2.0)
	denom := env.Mu_b + 2.0*env.Xi_h(k)
	return numer / denom
}
<|endoftext|>


<commit_before>package api

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"regexp"
	"runtime"
	"sort"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/swarm/cluster"
	"github.com/docker/swarm/scheduler"
	"github.com/gorilla/mux"
	"github.com/samalba/dockerclient"
)

type context struct {
	cluster       *cluster.Cluster
	scheduler     *scheduler.Scheduler
	eventsHandler *eventsHandler
	debug         bool
	version       string
}

type handler func(c *context, w http.ResponseWriter, r *http.Request)

// GET /info
func getInfo(c *context, w http.ResponseWriter, r *http.Request) {
	nodes := c.cluster.Nodes()
	driverStatus := [][2]string{{"\bNodes", fmt.Sprintf("%d", len(nodes))}}

	for _, node := range nodes {
		driverStatus = append(driverStatus, [2]string{node.Name, node.Addr})
	}
	info := struct {
		Containers      int
		DriverStatus    [][2]string
		NEventsListener int
		Debug           bool
	}{
		len(c.cluster.Containers()),
		driverStatus,
		c.eventsHandler.Size(),
		c.debug,
	}

	json.NewEncoder(w).Encode(info)
}

// GET /version
func getVersion(c *context, w http.ResponseWriter, r *http.Request) {
	version := struct {
		Version   string
		GoVersion string
		GitCommit string
	}{
		Version:   "swarm/" + c.version,
		GoVersion: runtime.Version(),
		GitCommit: "swarm",
	}

	json.NewEncoder(w).Encode(version)
}

// GET /containers/ps
// GET /containers/json
func getContainersJSON(c *context, w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	all := r.Form.Get("all") == "1"

	out := []*dockerclient.Container{}
	for _, container := range c.cluster.Containers() {
		tmp := (*container).Container
		// Skip stopped containers unless -a was specified.
		if !strings.Contains(tmp.Status, "Up") && !all {
			continue
		}
		if !container.Node().IsHealthy() {
			tmp.Status = "Pending"
		}
		// TODO remove the Node ID in the name when we have a good solution
		tmp.Names = make([]string, len(container.Names))
		for i, name := range container.Names {
			tmp.Names[i] = "/" + container.Node().Name + name
		}
		tmp.Ports = make([]dockerclient.Port, len(container.Ports))
		for i, port := range container.Ports {
			tmp.Ports[i] = port
			if port.IP == "0.0.0.0" {
				tmp.Ports[i].IP = container.Node().IP
			}
		}
		out = append(out, &tmp)
	}

	sort.Sort(sort.Reverse(ContainerSorter(out)))
	json.NewEncoder(w).Encode(out)
}

// GET /containers/{name:.*}/json
func getContainerJSON(c *context, w http.ResponseWriter, r *http.Request) {
	container := c.cluster.Container(mux.Vars(r)["name"])
	if container != nil {
		resp, err := http.Get(container.Node().Addr + "/containers/" + container.Id + "/json")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		data, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Write(bytes.Replace(data, []byte("\"HostIp\":\"0.0.0.0\""), []byte(fmt.Sprintf("\"HostIp\":%q", container.Node().IP)), -1))
	}
}

// POST /containers/create
func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	var (
		config dockerclient.ContainerConfig
		name   = r.Form.Get("name")
	)

	if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if config.AttachStdout || config.AttachStdin || config.AttachStderr {
		http.Error(w, "Attach is not supported in clustering mode, use -d.", http.StatusInternalServerError)
		return
	}

	if container := c.cluster.Container(name); container != nil {
		http.Error(w, fmt.Sprintf("Conflict, The name %s is already assigned to %s. You have to delete (or rename) that container to be able to assign %s to a container again.", name, container.Id, name), http.StatusConflict)
		return
	}

	container, err := c.scheduler.CreateContainer(&config, name)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
	return
}

// POST /containers/{name:.*}/start
func postContainersStart(c *context, w http.ResponseWriter, r *http.Request) {
	name := mux.Vars(r)["name"]
	container := c.cluster.Container(name)
	if container == nil {
		http.Error(w, fmt.Sprintf("Container %s not found", name), http.StatusNotFound)
		return
	}
	if err := container.Start(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
}

// POST /containers/{name:.*}/kill
func postContainerKill(c *context, w http.ResponseWriter, r *http.Request) {
	name := mux.Vars(r)["name"]
	container := c.cluster.Container(name)
	if container == nil {
		http.Error(w, fmt.Sprintf("Container %s not found", name), http.StatusNotFound)
		return
	}

	if err := container.Kill(r.Form.Get("signal")); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
}

// POST /containers/{name:.*}/pause
func postContainerPause(c *context, w http.ResponseWriter, r *http.Request) {
	name := mux.Vars(r)["name"]
	container := c.cluster.Container(name)
	if container == nil {
		http.Error(w, fmt.Sprintf("Container %s not found", name), http.StatusNotFound)
		return
	}
	if err := container.Pause(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
}

// POST /containers/{name:.*}/unpause
func postContainerUnpause(c *context, w http.ResponseWriter, r *http.Request) {
	name := mux.Vars(r)["name"]
	container := c.cluster.Container(name)
	if container == nil {
		http.Error(w, fmt.Sprintf("Container %s not found", name), http.StatusNotFound)
		return
	}
	if err := container.Unpause(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
}

// DELETE /containers/{name:.*}
func deleteContainer(c *context, w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	name := mux.Vars(r)["name"]
	force := r.Form.Get("force") == "1"
	container := c.cluster.Container(name)
	if container == nil {
		http.Error(w, fmt.Sprintf("Container %s not found", name), http.StatusNotFound)
		return
	}
	if err := c.scheduler.RemoveContainer(container, force); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

// GET /events
func getEvents(c *context, w http.ResponseWriter, r *http.Request) {
	c.eventsHandler.Add(r.RemoteAddr, w)

	w.Header().Set("Content-Type", "application/json")

	if f, ok := w.(http.Flusher); ok {
		f.Flush()
	}

	c.eventsHandler.Wait(r.RemoteAddr)
}

// GET /_ping
func ping(c *context, w http.ResponseWriter, r *http.Request) {
	w.Write([]byte{'O', 'K'})
}

// Redirect a GET request to the right node
func redirectContainer(c *context, w http.ResponseWriter, r *http.Request) {
	container := c.cluster.Container(mux.Vars(r)["name"])
	if container != nil {
		re := regexp.MustCompile("/v([0-9.]*)") // TODO: discuss about skipping the version or not

		newURL, _ := url.Parse(container.Node().Addr)
		newURL.RawQuery = r.URL.RawQuery
		newURL.Path = re.ReplaceAllLiteralString(r.URL.Path, "")
		log.Debugf("REDIRECT TO %s", newURL.String())
		http.Redirect(w, r, newURL.String(), http.StatusSeeOther)
	}
}

// Default handler for methods not supported by clustering.
func notImplementedHandler(c *context, w http.ResponseWriter, r *http.Request) {
	http.Error(w, "Not supported in clustering mode.", http.StatusNotImplemented)
}

func optionsHandler(c *context, w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
}

func writeCorsHeaders(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
	w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
}

func createRouter(c *context, enableCors bool) (*mux.Router, error) {
	r := mux.NewRouter()
	m := map[string]map[string]handler{
		"GET": {
			"/_ping":                          ping,
			"/events":                         getEvents,
			"/info":                           getInfo,
			"/version":                        getVersion,
			"/images/json":                    notImplementedHandler,
			"/images/viz":                     notImplementedHandler,
			"/images/search":                  notImplementedHandler,
			"/images/get":                     notImplementedHandler,
			"/images/{name:.*}/get":           notImplementedHandler,
			"/images/{name:.*}/history":       notImplementedHandler,
			"/images/{name:.*}/json":          notImplementedHandler,
			"/containers/ps":                  getContainersJSON,
			"/containers/json":                getContainersJSON,
			"/containers/{name:.*}/export":    redirectContainer,
			"/containers/{name:.*}/changes":   redirectContainer,
			"/containers/{name:.*}/json":      getContainerJSON,
			"/containers/{name:.*}/top":       redirectContainer,
			"/containers/{name:.*}/logs":      redirectContainer,
			"/containers/{name:.*}/attach/ws": notImplementedHandler,
		},
		"POST": {
			"/auth":                         notImplementedHandler,
			"/commit":                       notImplementedHandler,
			"/build":                        notImplementedHandler,
			"/images/create":                notImplementedHandler,
			"/images/load":                  notImplementedHandler,
			"/images/{name:.*}/push":        notImplementedHandler,
			"/images/{name:.*}/tag":         notImplementedHandler,
			"/containers/create":            postContainersCreate,
			"/containers/{name:.*}/kill":    postContainerKill,
			"/containers/{name:.*}/pause":   postContainerPause,
			"/containers/{name:.*}/unpause": postContainerUnpause,
			"/containers/{name:.*}/restart": notImplementedHandler,
			"/containers/{name:.*}/start":   postContainersStart,
			"/containers/{name:.*}/stop":    notImplementedHandler,
			"/containers/{name:.*}/wait":    notImplementedHandler,
			"/containers/{name:.*}/resize":  notImplementedHandler,
			"/containers/{name:.*}/attach":  notImplementedHandler,
			"/containers/{name:.*}/copy":    notImplementedHandler,
			"/containers/{name:.*}/exec":    notImplementedHandler,
			"/exec/{name:.*}/start":         notImplementedHandler,
			"/exec/{name:.*}/resize":        notImplementedHandler,
		},
		"DELETE": {
			"/containers/{name:.*}": deleteContainer,
			"/images/{name:.*}":     notImplementedHandler,
		},
		"OPTIONS": {
			"": optionsHandler,
		},
	}

	for method, routes := range m {
		for route, fct := range routes {
			log.Debugf("Registering %s, %s", method, route)

			// NOTE: scope issue, make sure the variables are local and won't be changed
			localRoute := route
			localFct := fct
			wrap := func(w http.ResponseWriter, r *http.Request) {
				log.Infof("%s %s", r.Method, r.RequestURI)
				if enableCors {
					writeCorsHeaders(w, r)
				}
				localFct(c, w, r)
			}
			localMethod := method

			// add the new route
			r.Path("/v{version:[0-9.]+}" + localRoute).Methods(localMethod).HandlerFunc(wrap)
			r.Path(localRoute).Methods(localMethod).HandlerFunc(wrap)
		}
	}

	return r, nil
}

func ListenAndServe(c *cluster.Cluster, s *scheduler.Scheduler, addr, version string, enableCors bool, tlsConfig *tls.Config) error {
	context := &context{
		cluster:       c,
		scheduler:     s,
		version:       version,
		eventsHandler: NewEventsHandler(),
	}
	c.Events(context.eventsHandler)
	r, err := createRouter(context, enableCors)
	if err != nil {
		return err
	}

	server := &http.Server{
		Addr:    addr,
		Handler: r,
	}

	l, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}
	if tlsConfig != nil {
		tlsConfig.NextProtos = []string{"http/1.1"}
		l = tls.NewListener(l, tlsConfig)
	}
	return server.Serve(l)
}
<commit_msg>proxy simple requests<commit_after>package api

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"runtime"
	"sort"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/swarm/cluster"
	"github.com/docker/swarm/scheduler"
	"github.com/gorilla/mux"
	"github.com/samalba/dockerclient"
)

type context struct {
	cluster       *cluster.Cluster
	scheduler     *scheduler.Scheduler
	eventsHandler *eventsHandler
	debug         bool
	version       string
}

type handler func(c *context, w http.ResponseWriter, r *http.Request)

// GET /info
func getInfo(c *context, w http.ResponseWriter, r *http.Request) {
	nodes := c.cluster.Nodes()
	driverStatus := [][2]string{{"\bNodes", fmt.Sprintf("%d", len(nodes))}}

	for _, node := range nodes {
		driverStatus = append(driverStatus, [2]string{node.Name, node.Addr})
	}
	info := struct {
		Containers      int
		DriverStatus    [][2]string
		NEventsListener int
		Debug           bool
	}{
		len(c.cluster.Containers()),
		driverStatus,
		c.eventsHandler.Size(),
		c.debug,
	}

	json.NewEncoder(w).Encode(info)
}

// GET /version
func getVersion(c *context, w http.ResponseWriter, r *http.Request) {
	version := struct {
		Version   string
		GoVersion string
		GitCommit string
	}{
		Version:   "swarm/" + c.version,
		GoVersion: runtime.Version(),
		GitCommit: "swarm",
	}

	json.NewEncoder(w).Encode(version)
}

// GET /containers/ps
// GET /containers/json
func getContainersJSON(c *context, w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	all := r.Form.Get("all") == "1"

	out := []*dockerclient.Container{}
	for _, container := range c.cluster.Containers() {
		tmp := (*container).Container
		// Skip stopped containers unless -a was specified.
		if !strings.Contains(tmp.Status, "Up") && !all {
			continue
		}
		if !container.Node().IsHealthy() {
			tmp.Status = "Pending"
		}
		// TODO remove the Node ID in the name when we have a good solution
		tmp.Names = make([]string, len(container.Names))
		for i, name := range container.Names {
			tmp.Names[i] = "/" + container.Node().Name + name
		}
		tmp.Ports = make([]dockerclient.Port, len(container.Ports))
		for i, port := range container.Ports {
			tmp.Ports[i] = port
			if port.IP == "0.0.0.0" {
				tmp.Ports[i].IP = container.Node().IP
			}
		}
		out = append(out, &tmp)
	}

	sort.Sort(sort.Reverse(ContainerSorter(out)))
	json.NewEncoder(w).Encode(out)
}

// GET /containers/{name:.*}/json
func getContainerJSON(c *context, w http.ResponseWriter, r *http.Request) {
	container := c.cluster.Container(mux.Vars(r)["name"])
	if container != nil {
		resp, err := http.Get(container.Node().Addr + "/containers/" + container.Id + "/json")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		data, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		w.Write(bytes.Replace(data, []byte("\"HostIp\":\"0.0.0.0\""), []byte(fmt.Sprintf("\"HostIp\":%q", container.Node().IP)), -1))
	}
}

// POST /containers/create
func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	var (
		config dockerclient.ContainerConfig
		name   = r.Form.Get("name")
	)

	if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if config.AttachStdout || config.AttachStdin || config.AttachStderr {
		http.Error(w, "Attach is not supported in clustering mode, use -d.", http.StatusInternalServerError)
		return
	}

	if container := c.cluster.Container(name); container != nil {
		http.Error(w, fmt.Sprintf("Conflict, The name %s is already assigned to %s. You have to delete (or rename) that container to be able to assign %s to a container again.", name, container.Id, name), http.StatusConflict)
		return
	}

	container, err := c.scheduler.CreateContainer(&config, name)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
	return
}

// DELETE /containers/{name:.*}
func deleteContainer(c *context, w http.ResponseWriter, r *http.Request) {
	if err := r.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	name := mux.Vars(r)["name"]
	force := r.Form.Get("force") == "1"
	container := c.cluster.Container(name)
	if container == nil {
		http.Error(w, fmt.Sprintf("Container %s not found", name), http.StatusNotFound)
		return
	}
	if err := c.scheduler.RemoveContainer(container, force); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

}

// GET /events
func getEvents(c *context, w http.ResponseWriter, r *http.Request) {
	c.eventsHandler.Add(r.RemoteAddr, w)

	w.Header().Set("Content-Type", "application/json")

	if f, ok := w.(http.Flusher); ok {
		f.Flush()
	}

	c.eventsHandler.Wait(r.RemoteAddr)
}

// GET /_ping
func ping(c *context, w http.ResponseWriter, r *http.Request) {
	w.Write([]byte{'O', 'K'})
}

// Proxy a request to the right node
func proxyContainer(c *context, w http.ResponseWriter, r *http.Request) {
	container := c.cluster.Container(mux.Vars(r)["name"])
	if container != nil {

		// Use a new client for each request
		client := &http.Client{}

		// RequestURI may not be sent to client
		r.RequestURI = ""

		parts := strings.SplitN(container.Node().Addr, "://", 2)
		if len(parts) == 2 {
			r.URL.Scheme = parts[0]
			r.URL.Host = parts[1]
		} else {
			r.URL.Scheme = "http"
			r.URL.Host = parts[0]
		}

		log.Println("[PROXY] -->", r.Method, r.URL)
		resp, err := client.Do(r)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		io.Copy(w, resp.Body)
	}
}

// Default handler for methods not supported by clustering.
func notImplementedHandler(c *context, w http.ResponseWriter, r *http.Request) {
	http.Error(w, "Not supported in clustering mode.", http.StatusNotImplemented)
}

func optionsHandler(c *context, w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusOK)
}

func writeCorsHeaders(w http.ResponseWriter, r *http.Request) {
	w.Header().Add("Access-Control-Allow-Origin", "*")
	w.Header().Add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
	w.Header().Add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS")
}

func createRouter(c *context, enableCors bool) (*mux.Router, error) {
	r := mux.NewRouter()
	m := map[string]map[string]handler{
		"GET": {
			"/_ping":                          ping,
			"/events":                         getEvents,
			"/info":                           getInfo,
			"/version":                        getVersion,
			"/images/json":                    notImplementedHandler,
			"/images/viz":                     notImplementedHandler,
			"/images/search":                  notImplementedHandler,
			"/images/get":                     notImplementedHandler,
			"/images/{name:.*}/get":           notImplementedHandler,
			"/images/{name:.*}/history":       notImplementedHandler,
			"/images/{name:.*}/json":          notImplementedHandler,
			"/containers/ps":                  getContainersJSON,
			"/containers/json":                getContainersJSON,
			"/containers/{name:.*}/export":    proxyContainer,
			"/containers/{name:.*}/changes":   proxyContainer,
			"/containers/{name:.*}/json":      getContainerJSON,
			"/containers/{name:.*}/top":       proxyContainer,
			"/containers/{name:.*}/logs":      proxyContainer,
			"/containers/{name:.*}/attach/ws": notImplementedHandler,
			"/exec/{id:.*}/json":              proxyContainer,
		},
		"POST": {
			"/auth":                         notImplementedHandler,
			"/commit":                       notImplementedHandler,
			"/build":                        notImplementedHandler,
			"/images/create":                notImplementedHandler,
			"/images/load":                  notImplementedHandler,
			"/images/{name:.*}/push":        notImplementedHandler,
			"/images/{name:.*}/tag":         notImplementedHandler,
			"/containers/create":            postContainersCreate,
			"/containers/{name:.*}/kill":    proxyContainer,
			"/containers/{name:.*}/pause":   proxyContainer,
			"/containers/{name:.*}/unpause": proxyContainer,
			"/containers/{name:.*}/restart": proxyContainer,
			"/containers/{name:.*}/start":   proxyContainer,
			"/containers/{name:.*}/stop":    proxyContainer,
			"/containers/{name:.*}/wait":    proxyContainer,
			"/containers/{name:.*}/resize":  proxyContainer,
			"/containers/{name:.*}/attach":  notImplementedHandler,
			"/containers/{name:.*}/copy":    notImplementedHandler,
			"/containers/{name:.*}/exec":    notImplementedHandler,
			"/exec/{name:.*}/start":         notImplementedHandler,
			"/exec/{name:.*}/resize":        proxyContainer,
		},
		"DELETE": {
			"/containers/{name:.*}": deleteContainer,
			"/images/{name:.*}":     notImplementedHandler,
		},
		"OPTIONS": {
			"": optionsHandler,
		},
	}

	for method, routes := range m {
		for route, fct := range routes {
			log.Debugf("Registering %s, %s", method, route)

			// NOTE: scope issue, make sure the variables are local and won't be changed
			localRoute := route
			localFct := fct
			wrap := func(w http.ResponseWriter, r *http.Request) {
				log.Infof("%s %s", r.Method, r.RequestURI)
				if enableCors {
					writeCorsHeaders(w, r)
				}
				localFct(c, w, r)
			}
			localMethod := method

			// add the new route
			r.Path("/v{version:[0-9.]+}" + localRoute).Methods(localMethod).HandlerFunc(wrap)
			r.Path(localRoute).Methods(localMethod).HandlerFunc(wrap)
		}
	}

	return r, nil
}

func ListenAndServe(c *cluster.Cluster, s *scheduler.Scheduler, addr, version string, enableCors bool, tlsConfig *tls.Config) error {
	context := &context{
		cluster:       c,
		scheduler:     s,
		version:       version,
		eventsHandler: NewEventsHandler(),
	}
	c.Events(context.eventsHandler)
	r, err := createRouter(context, enableCors)
	if err != nil {
		return err
	}

	server := &http.Server{
		Addr:    addr,
		Handler: r,
	}

	l, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}
	if tlsConfig != nil {
		tlsConfig.NextProtos = []string{"http/1.1"}
		l = tls.NewListener(l, tlsConfig)
	}
	return server.Serve(l)
}
<|endoftext|>


<commit_before><commit_msg>Add a comment to SQL<commit_after><|endoftext|>


<commit_before>package main

import (
	"fmt"
	"testing"
	"time"
)

//updater: Perform atomic updates to row 1 of the matrix
func updater(M *Matrix, ch chan int64) {
	var i, j int64
	for i = 0; i < M.Ncols; i++ {
		for j = 0; j < 100; j++ {
			M.AtomicAdd(1, i, 1)
		}
	}
	ch <- 1
}

//raceyUpdater: Perform unsynchronized updates to row 0 of the matrix
func raceyUpdater(M *Matrix, ch chan int64) {
	var i, j int64
	for i = 0; i < M.Ncols; i++ {
		for j = 0; j < 100; j++ {
			M.Add(0, i, 1)
		}
	}
	ch <- 1
}
func TestRacey(t *testing.T) {
	M := NewMatrix(2, 4)
	var k, rounds int64
	rounds = 500
	fmt.Println(M)
	ch := make(chan int64, rounds)
	ts := time.Now()
	for k = 0; k < rounds; k++ {
		go updater(&M, ch)
	}
	for k = 0; k < rounds; k++ {
		<-ch
	}
	timeAtomic := time.Now().Sub(ts)
	var i int64
	for i = 0; i < M.Ncols; i++ {
		if M.Read(1, i) != rounds*100 {
			t.Errorf("Atomics did not work: 1,%d\n", i)
		}
	}
	t.Logf("Post Atomics:\n%v\n", M)
	ts = time.Now()
	for k = 0; k < rounds; k++ {
		go raceyUpdater(&M, ch)
	}
	for k = 0; k < rounds; k++ {
		<-ch
	}
	for i = 0; i < M.Ncols; i++ {
		if M.Read(0, i) == rounds*100 {
			t.Errorf("Race condition did not appear 0,%d\n", i)
		}
	}
	t.Logf("Post Racey:\n%v\n", M)
	timeRacey := time.Now().Sub(ts)
	fmt.Printf("time atomic: %d\n", timeAtomic)
	fmt.Printf("time racey: %d\n", timeRacey)
	fmt.Printf("atomic/racey: %d\n", timeAtomic/timeRacey)
}

func TestString(t *testing.T) {
	rightS := "[0 0 0 0]\n[0 0 0 0]"
	M := NewMatrix(2, 4)
	S := M.String()
	fmt.Println(S)
	if S != rightS {
		t.Errorf(S)
	}
}

//TestEqual: make sure that we can test for deep equality
func TestEqual(t *testing.T) {
	M := NewMatrix(2, 4)
	other := NewMatrix(2, 5)
	if M.Equal(&other) {
		t.Errorf("Failed on different sized matrices\n")
	}
	other = NewMatrix(2, 4)
	if !M.Equal(&other) {
		t.Errorf("False negative on zeros")
	}
	other.Data[0] = 1
	if M.Equal(&other) {
		t.Errorf("False positive")
	}
}
<commit_msg>fixing test case for printing a matrix<commit_after>package main

import (
	"fmt"
	"testing"
	"time"
)

//updater: Perform atomic updates to row 1 of the matrix
func updater(M *Matrix, ch chan int64) {
	var i, j int64
	for i = 0; i < M.Ncols; i++ {
		for j = 0; j < 100; j++ {
			M.AtomicAdd(1, i, 1)
		}
	}
	ch <- 1
}

//raceyUpdater: Perform unsynchronized updates to row 0 of the matrix
func raceyUpdater(M *Matrix, ch chan int64) {
	var i, j int64
	for i = 0; i < M.Ncols; i++ {
		for j = 0; j < 100; j++ {
			M.Add(0, i, 1)
		}
	}
	ch <- 1
}
func TestRacey(t *testing.T) {
	M := NewMatrix(2, 4)
	var k, rounds int64
	rounds = 500
	fmt.Println(M)
	ch := make(chan int64, rounds)
	ts := time.Now()
	for k = 0; k < rounds; k++ {
		go updater(&M, ch)
	}
	for k = 0; k < rounds; k++ {
		<-ch
	}
	timeAtomic := time.Now().Sub(ts)
	var i int64
	for i = 0; i < M.Ncols; i++ {
		if M.Read(1, i) != rounds*100 {
			t.Errorf("Atomics did not work: 1,%d\n", i)
		}
	}
	t.Logf("Post Atomics:\n%v\n", M)
	ts = time.Now()
	for k = 0; k < rounds; k++ {
		go raceyUpdater(&M, ch)
	}
	for k = 0; k < rounds; k++ {
		<-ch
	}
	for i = 0; i < M.Ncols; i++ {
		if M.Read(0, i) == rounds*100 {
			t.Errorf("Race condition did not appear 0,%d\n", i)
		}
	}
	t.Logf("Post Racey:\n%v\n", M)
	timeRacey := time.Now().Sub(ts)
	fmt.Printf("time atomic: %d\n", timeAtomic)
	fmt.Printf("time racey: %d\n", timeRacey)
	fmt.Printf("atomic/racey: %d\n", timeAtomic/timeRacey)
}

func TestString(t *testing.T) {
	rightS := "[0 0 0 0]\n[0 0 0 0]"
	M := NewMatrix(2, 4)
	S := M.String()
	t.Logf("%s\n", S)
	if S != rightS {
		t.Errorf(S)
	}
}

//TestEqual: make sure that we can test for deep equality
func TestEqual(t *testing.T) {
	M := NewMatrix(2, 4)
	other := NewMatrix(2, 5)
	if M.Equal(&other) {
		t.Errorf("Failed on different sized matrices\n")
	}
	other = NewMatrix(2, 4)
	if !M.Equal(&other) {
		t.Errorf("False negative on zeros")
	}
	other.Data[0] = 1
	if M.Equal(&other) {
		t.Errorf("False positive")
	}
}
<|endoftext|>