<commit_before>package discorddotgo

import "github.com/bwmarrin/discordgo"

type Context struct {
	intSession *discordgo.Session
	exit       chan bool
}

func (c Context) int() *discordgo.Session {
	return c.intSession
}

func (c Context) ChannelFromID(id string) (*Channel, error) {
	u, err := c.intSession.Channel(id)
	if err != nil {
		return nil, err
	}
	return c.channelFromRaw(u), nil
}

func (c Context) channelFromRaw(ch *discordgo.Channel) *Channel {
	return &Channel{context: c, intChannel: ch}
}

func (c Context) UserFromID(id string) (*User, error) {
	u, err := c.intSession.User(id)
	if err != nil {
		return nil, err
	}
	return c.userFromRaw(u), nil
}

func (c Context) userFromRaw(us *discordgo.User) *User {
	return &User{context: c, internalUser: us}
}

func (c Context) GuildFromID(id string) (*Guild, error) {
	u, err := c.intSession.Guild(id)
	if err != nil {
		return nil, err
	}
	return c.guildFromRaw(u), nil
}

func (c Context) guildFromRaw(g *discordgo.Guild) *Guild {
	return &Guild{context: c, intGuild: g}
}

func (c Context) InviteFromID(id string) (*Invite, error) {
	i, err := c.int().Invite(id)
	if err != nil {
		return nil, err
	}
	return c.inviteFromRaw(i), nil
}

func (c Context) inviteFromRaw(i *discordgo.Invite) *Invite {
	return &Invite{context: c, intInvite: i}
}

func (c Context) messageFromRaw(m *discordgo.Message) *Message {
	return &Message{context: c, intMessage: m}
}

func (c Context) memberFromRaw(m *discordgo.Member) *Member {
	return &Member{context: c, internalMember: m}
}

func (c Context) roleFromRaw(r *discordgo.Role) *Role {
	return &Role{context: c, intRole: r}
}

func (c Context) Self() *User {
	u, err := c.UserFromID("@me")
	if err != nil {
		panic(err)
	}
	return u
}

func (c Context) RequestExit() {
	c.exit <- true
}
<commit_msg>Added RoleFromID to context and some documentation<commit_after>package discorddotgo

import "github.com/bwmarrin/discordgo"

// Context represents a particular Discord Session. It is available to all
// objects it spawns. If operating a user, it will usually contain a context
// and give all objects it creates the context too. This allows to
// access the DiscordSession from everywhere, thus allowing to use any method of
// a type in any code context.
//
// An example would be to ban a user that has a mention in a message received.
// Simply retrieve the mention, get the user object from this mention and
// call the Ban() method on the user.
type Context struct {
	intSession *discordgo.Session
	exit       chan bool
}

func (c Context) int() *discordgo.Session {
	return c.intSession
}

// ChannelFromID converts a ChannelID to a Channel instance or returns an error
func (c Context) ChannelFromID(id string) (*Channel, error) {
	u, err := c.intSession.Channel(id)
	if err != nil {
		return nil, err
	}
	return c.channelFromRaw(u), nil
}

func (c Context) channelFromRaw(ch *discordgo.Channel) *Channel {
	return &Channel{context: c, intChannel: ch}
}

// UserFromID converts a UserID to a User instance or returns an error
func (c Context) UserFromID(id string) (*User, error) {
	u, err := c.intSession.User(id)
	if err != nil {
		return nil, err
	}
	return c.userFromRaw(u), nil
}

func (c Context) userFromRaw(us *discordgo.User) *User {
	return &User{context: c, internalUser: us}
}

// GuildFromID converts a GuildID to a Guild instance or return an error
func (c Context) GuildFromID(id string) (*Guild, error) {
	u, err := c.intSession.Guild(id)
	if err != nil {
		return nil, err
	}
	return c.guildFromRaw(u), nil
}

func (c Context) guildFromRaw(g *discordgo.Guild) *Guild {
	return &Guild{context: c, intGuild: g}
}

// InviteFromID converts a InviteID to an Invite instance or returns an error
func (c Context) InviteFromID(id string) (*Invite, error) {
	i, err := c.int().Invite(id)
	if err != nil {
		return nil, err
	}
	return c.inviteFromRaw(i), nil
}

func (c Context) inviteFromRaw(i *discordgo.Invite) *Invite {
	return &Invite{context: c, intInvite: i}
}

func (c Context) messageFromRaw(m *discordgo.Message) *Message {
	return &Message{context: c, intMessage: m}
}

func (c Context) memberFromRaw(m *discordgo.Member) *Member {
	return &Member{context: c, internalMember: m}
}

func (c Context) roleFromRaw(r *discordgo.Role) *Role {
	return &Role{context: c, intRole: r}
}

func (c Context) RoleFromID(gid, id string) (*Role, error) {
	r, err := c.int().State.Role(gid, id)
	if err != nil {
		return nil, err
	}
	return &Role{intRole: r, context: c}, nil
}

// Self returns the Context user. If the context has no user, it panics.
func (c Context) Self() *User {
	u, err := c.UserFromID("@me")
	if err != nil {
		log.Fatal("I am not a user!")
	}
	return u
}

// RequestExit will send a value to the exit channel. If your bot is blocking
// on BlockForExit() it will return from this function. Beware that this function
// will block if the bot is not waiting on it.
func (c Context) RequestExit() {
	c.exit <- true
}
<|endoftext|>


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

package macaron

import (
	"crypto/md5"
	"encoding/hex"
	"html/template"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"path"
	"path/filepath"
	"reflect"
	"strings"
	"time"

	"github.com/Unknwon/com"

	"github.com/Unknwon/macaron/inject"
)

// Locale reprents a localization interface.
type Locale interface {
	Language() string
	Tr(string, ...interface{}) string
}

// RequestBody represents a request body.
type RequestBody struct {
	reader io.ReadCloser
}

// Bytes reads and returns content of request body in bytes.
func (rb *RequestBody) Bytes() ([]byte, error) {
	return ioutil.ReadAll(rb.reader)
}

// String reads and returns content of request body in string.
func (rb *RequestBody) String() (string, error) {
	data, err := rb.Bytes()
	return string(data), err
}

// ReadCloser returns a ReadCloser for request body.
func (rb *RequestBody) ReadCloser() io.ReadCloser {
	return rb.reader
}

// Request represents an HTTP request received by a server or to be sent by a client.
type Request struct {
	*http.Request
}

func (r *Request) Body() *RequestBody {
	return &RequestBody{r.Request.Body}
}

// Context represents the runtime context of current request of Macaron instance.
// It is the integration of most frequently used middlewares and helper methods.
type Context struct {
	inject.Injector
	handlers []Handler
	action   Handler
	index    int

	*Router
	Req    Request
	Resp   ResponseWriter
	params Params
	Render // Not nil only if you use macaran.Render middleware.
	Locale
	Data map[string]interface{}
}

func (c *Context) handler() Handler {
	if c.index < len(c.handlers) {
		return c.handlers[c.index]
	}
	if c.index == len(c.handlers) {
		return c.action
	}
	panic("invalid index for context handler")
}

func (c *Context) Next() {
	c.index += 1
	c.run()
}

func (c *Context) Written() bool {
	return c.Resp.Written()
}

func (c *Context) run() {
	for c.index <= len(c.handlers) {
		vals, err := c.Invoke(c.handler())
		if err != nil {
			panic(err)
		}
		c.index += 1

		// if the handler returned something, write it to the http response
		if len(vals) > 0 {
			ev := c.GetVal(reflect.TypeOf(ReturnHandler(nil)))
			handleReturn := ev.Interface().(ReturnHandler)
			handleReturn(c, vals)
		}

		if c.Written() {
			return
		}
	}
}

// RemoteAddr returns more real IP address.
func (ctx *Context) RemoteAddr() string {
	addr := ctx.Req.Header.Get("X-Real-IP")
	if len(addr) == 0 {
		addr = ctx.Req.Header.Get("X-Forwarded-For")
		if addr == "" {
			addr = ctx.Req.RemoteAddr
			if i := strings.LastIndex(addr, ":"); i > -1 {
				addr = addr[:i]
			}
		}
	}
	return addr
}

func (ctx *Context) renderHTML(status int, setName, tplName string, data ...interface{}) {
	if ctx.Render == nil {
		panic("renderer middleware hasn't been registered")
	}
	if len(data) == 0 {
		ctx.Render.HTMLSet(status, setName, tplName, ctx.Data)
	} else {
		ctx.Render.HTMLSet(status, setName, tplName, data[0])
		if len(data) > 1 {
			ctx.Render.HTMLSet(status, setName, tplName, data[0], data[1].(HTMLOptions))
		}
	}
}

// HTML calls Render.HTML but allows less arguments.
func (ctx *Context) HTML(status int, name string, data ...interface{}) {
	ctx.renderHTML(status, _DEFAULT_TPL_SET_NAME, name, data...)
}

// HTML calls Render.HTMLSet but allows less arguments.
func (ctx *Context) HTMLSet(status int, setName, tplName string, data ...interface{}) {
	ctx.renderHTML(status, setName, tplName, data...)
}

func (ctx *Context) Redirect(location string, status ...int) {
	code := http.StatusFound
	if len(status) == 1 {
		code = status[0]
	}

	http.Redirect(ctx.Resp, ctx.Req.Request, location, code)
}

// Query querys form parameter.
func (ctx *Context) Query(name string) string {
	if ctx.Req.Form == nil {
		ctx.Req.ParseForm()
	}
	return ctx.Req.Form.Get(name)
}

// QueryStrings returns a list of results by given query name.
func (ctx *Context) QueryStrings(name string) []string {
	if ctx.Req.Form == nil {
		ctx.Req.ParseForm()
	}

	vals, ok := ctx.Req.Form[name]
	if !ok {
		return []string{}
	}
	return vals
}

// QueryEscape returns escapred query result.
func (ctx *Context) QueryEscape(name string) string {
	return template.HTMLEscapeString(ctx.Query(name))
}

// QueryInt returns query result in int type.
func (ctx *Context) QueryInt(name string) int {
	return com.StrTo(ctx.Query(name)).MustInt()
}

// QueryInt64 returns query result in int64 type.
func (ctx *Context) QueryInt64(name string) int64 {
	return com.StrTo(ctx.Query(name)).MustInt64()
}

// Params returns value of given param name.
func (ctx *Context) Params(name string) string {
	return ctx.params[name]
}

// ParamsEscape returns escapred params result.
func (ctx *Context) ParamsEscape(name string) string {
	return template.HTMLEscapeString(ctx.Params(name))
}

// ParamsInt returns params result in int type.
func (ctx *Context) ParamsInt(name string) int {
	return com.StrTo(ctx.Params(name)).MustInt()
}

// ParamsInt64 returns params result in int64 type.
func (ctx *Context) ParamsInt64(name string) int64 {
	return com.StrTo(ctx.Params(name)).MustInt64()
}

// GetFile returns information about user upload file by given form field name.
func (ctx *Context) GetFile(name string) (multipart.File, *multipart.FileHeader, error) {
	return ctx.Req.FormFile(name)
}

// SetCookie sets given cookie value to response header.
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
	cookie := http.Cookie{}
	cookie.Name = name
	cookie.Value = value

	if len(others) > 0 {
		switch v := others[0].(type) {
		case int:
			cookie.MaxAge = v
		case int64:
			cookie.MaxAge = int(v)
		case int32:
			cookie.MaxAge = int(v)
		}
	}

	// default "/"
	if len(others) > 1 {
		if v, ok := others[1].(string); ok && len(v) > 0 {
			cookie.Path = v
		}
	} else {
		cookie.Path = "/"
	}

	// default empty
	if len(others) > 2 {
		if v, ok := others[2].(string); ok && len(v) > 0 {
			cookie.Domain = v
		}
	}

	// default empty
	if len(others) > 3 {
		switch v := others[3].(type) {
		case bool:
			cookie.Secure = v
		default:
			if others[3] != nil {
				cookie.Secure = true
			}
		}
	}

	// default false. for session cookie default true
	if len(others) > 4 {
		if v, ok := others[4].(bool); ok && v {
			cookie.HttpOnly = true
		}
	}

	ctx.Resp.Header().Add("Set-Cookie", cookie.String())
}

// GetCookie returns given cookie value from request header.
func (ctx *Context) GetCookie(name string) string {
	cookie, err := ctx.Req.Cookie(name)
	if err != nil {
		return ""
	}
	return cookie.Value
}

// GetCookieInt returns cookie result in int type.
func (ctx *Context) GetCookieInt(name string) int {
	return com.StrTo(ctx.GetCookie(name)).MustInt()
}

// GetCookieInt64 returns cookie result in int64 type.
func (ctx *Context) GetCookieInt64(name string) int64 {
	return com.StrTo(ctx.GetCookie(name)).MustInt64()
}

var defaultCookieSecret string

// SetDefaultCookieSecret sets global default secure cookie secret.
func (m *Macaron) SetDefaultCookieSecret(secret string) {
	defaultCookieSecret = secret
}

// SetSecureCookie sets given cookie value to response header with default secret string.
func (ctx *Context) SetSecureCookie(name, value string, others ...interface{}) {
	ctx.SetSuperSecureCookie(defaultCookieSecret, name, value, others...)
}

// GetSecureCookie returns given cookie value from request header with default secret string.
func (ctx *Context) GetSecureCookie(key string) (string, bool) {
	return ctx.GetSuperSecureCookie(defaultCookieSecret, key)
}

// SetSuperSecureCookie sets given cookie value to response header with secret string.
func (ctx *Context) SetSuperSecureCookie(secret, name, value string, others ...interface{}) {
	m := md5.Sum([]byte(secret))
	secret = hex.EncodeToString(m[:])
	text, err := com.AESEncrypt([]byte(secret), []byte(value))
	if err != nil {
		panic("error encrypting cookie: " + err.Error())
	}
	ctx.SetCookie(name, hex.EncodeToString(text), others...)
}

// GetSuperSecureCookie returns given cookie value from request header with secret string.
func (ctx *Context) GetSuperSecureCookie(secret, key string) (string, bool) {
	val := ctx.GetCookie(key)
	if val == "" {
		return "", false
	}

	data, err := hex.DecodeString(val)
	if err != nil {
		return "", false
	}

	m := md5.Sum([]byte(secret))
	secret = hex.EncodeToString(m[:])
	text, err := com.AESDecrypt([]byte(secret), data)
	return string(text), err == nil
}

// ServeContent serves given content to response.
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
	modtime := time.Now()
	for _, p := range params {
		switch v := p.(type) {
		case time.Time:
			modtime = v
		}
	}
	ctx.Resp.Header().Set("Content-Description", "Raw content")
	ctx.Resp.Header().Set("Content-Type", "text/plain")
	ctx.Resp.Header().Set("Expires", "0")
	ctx.Resp.Header().Set("Cache-Control", "must-revalidate")
	ctx.Resp.Header().Set("Pragma", "public")
	http.ServeContent(ctx.Resp, ctx.Req.Request, name, modtime, r)
}

// ServeFile serves given file to response.
func (ctx *Context) ServeFile(file string, names ...string) {
	var name string
	if len(names) > 0 {
		name = names[0]
	} else {
		name = path.Base(file)
	}
	ctx.Resp.Header().Set("Content-Description", "File Transfer")
	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+name)
	ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary")
	ctx.Resp.Header().Set("Expires", "0")
	ctx.Resp.Header().Set("Cache-Control", "must-revalidate")
	ctx.Resp.Header().Set("Pragma", "public")
	http.ServeFile(ctx.Resp, ctx.Req.Request, file)
}

// ChangeStaticPath changes static path from old to new one.
func (ctx *Context) ChangeStaticPath(oldPath, newPath string) {
	if !filepath.IsAbs(oldPath) {
		oldPath = filepath.Join(Root, oldPath)
	}
	dir := statics.Get(oldPath)
	if dir != nil {
		statics.Delete(oldPath)

		if !filepath.IsAbs(newPath) {
			newPath = filepath.Join(Root, newPath)
		}
		*dir = http.Dir(newPath)
		statics.Set(dir)
	}
}
<commit_msg>mirror fix<commit_after>// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package macaron

import (
	"crypto/md5"
	"encoding/hex"
	"html/template"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"path"
	"path/filepath"
	"reflect"
	"strings"
	"time"

	"github.com/Unknwon/com"

	"github.com/Unknwon/macaron/inject"
)

// Locale reprents a localization interface.
type Locale interface {
	Language() string
	Tr(string, ...interface{}) string
}

// RequestBody represents a request body.
type RequestBody struct {
	reader io.ReadCloser
}

// Bytes reads and returns content of request body in bytes.
func (rb *RequestBody) Bytes() ([]byte, error) {
	return ioutil.ReadAll(rb.reader)
}

// String reads and returns content of request body in string.
func (rb *RequestBody) String() (string, error) {
	data, err := rb.Bytes()
	return string(data), err
}

// ReadCloser returns a ReadCloser for request body.
func (rb *RequestBody) ReadCloser() io.ReadCloser {
	return rb.reader
}

// Request represents an HTTP request received by a server or to be sent by a client.
type Request struct {
	*http.Request
}

func (r *Request) Body() *RequestBody {
	return &RequestBody{r.Request.Body}
}

// Context represents the runtime context of current request of Macaron instance.
// It is the integration of most frequently used middlewares and helper methods.
type Context struct {
	inject.Injector
	handlers []Handler
	action   Handler
	index    int

	*Router
	Req    Request
	Resp   ResponseWriter
	params Params
	Render // Not nil only if you use macaran.Render middleware.
	Locale
	Data map[string]interface{}
}

func (c *Context) handler() Handler {
	if c.index < len(c.handlers) {
		return c.handlers[c.index]
	}
	if c.index == len(c.handlers) {
		return c.action
	}
	panic("invalid index for context handler")
}

func (c *Context) Next() {
	c.index += 1
	c.run()
}

func (c *Context) Written() bool {
	return c.Resp.Written()
}

func (c *Context) run() {
	for c.index <= len(c.handlers) {
		vals, err := c.Invoke(c.handler())
		if err != nil {
			panic(err)
		}
		c.index += 1

		// if the handler returned something, write it to the http response
		if len(vals) > 0 {
			ev := c.GetVal(reflect.TypeOf(ReturnHandler(nil)))
			handleReturn := ev.Interface().(ReturnHandler)
			handleReturn(c, vals)
		}

		if c.Written() {
			return
		}
	}
}

// RemoteAddr returns more real IP address.
func (ctx *Context) RemoteAddr() string {
	addr := ctx.Req.Header.Get("X-Real-IP")
	if len(addr) == 0 {
		addr = ctx.Req.Header.Get("X-Forwarded-For")
		if addr == "" {
			addr = ctx.Req.RemoteAddr
			if i := strings.LastIndex(addr, ":"); i > -1 {
				addr = addr[:i]
			}
		}
	}
	return addr
}

func (ctx *Context) renderHTML(status int, setName, tplName string, data ...interface{}) {
	if ctx.Render == nil {
		panic("renderer middleware hasn't been registered")
	}
	if len(data) == 0 {
		ctx.Render.HTMLSet(status, setName, tplName, ctx.Data)
	} else {
		ctx.Render.HTMLSet(status, setName, tplName, data[0])
		if len(data) > 1 {
			ctx.Render.HTMLSet(status, setName, tplName, data[0], data[1].(HTMLOptions))
		}
	}
}

// HTML calls Render.HTML but allows less arguments.
func (ctx *Context) HTML(status int, name string, data ...interface{}) {
	ctx.renderHTML(status, _DEFAULT_TPL_SET_NAME, name, data...)
}

// HTML calls Render.HTMLSet but allows less arguments.
func (ctx *Context) HTMLSet(status int, setName, tplName string, data ...interface{}) {
	ctx.renderHTML(status, setName, tplName, data...)
}

func (ctx *Context) Redirect(location string, status ...int) {
	code := http.StatusFound
	if len(status) == 1 {
		code = status[0]
	}

	http.Redirect(ctx.Resp, ctx.Req.Request, location, code)
}

// Query querys form parameter.
func (ctx *Context) Query(name string) string {
	if ctx.Req.Form == nil {
		ctx.Req.ParseForm()
	}
	return ctx.Req.Form.Get(name)
}

// QueryStrings returns a list of results by given query name.
func (ctx *Context) QueryStrings(name string) []string {
	if ctx.Req.Form == nil {
		ctx.Req.ParseForm()
	}

	vals, ok := ctx.Req.Form[name]
	if !ok {
		return []string{}
	}
	return vals
}

// QueryEscape returns escapred query result.
func (ctx *Context) QueryEscape(name string) string {
	return template.HTMLEscapeString(ctx.Query(name))
}

// QueryInt returns query result in int type.
func (ctx *Context) QueryInt(name string) int {
	return com.StrTo(ctx.Query(name)).MustInt()
}

// QueryInt64 returns query result in int64 type.
func (ctx *Context) QueryInt64(name string) int64 {
	return com.StrTo(ctx.Query(name)).MustInt64()
}

// Params returns value of given param name.
func (ctx *Context) Params(name string) string {
	return ctx.params[name]
}

// ParamsEscape returns escapred params result.
func (ctx *Context) ParamsEscape(name string) string {
	return template.HTMLEscapeString(ctx.Params(name))
}

// ParamsInt returns params result in int type.
func (ctx *Context) ParamsInt(name string) int {
	return com.StrTo(ctx.Params(name)).MustInt()
}

// ParamsInt64 returns params result in int64 type.
func (ctx *Context) ParamsInt64(name string) int64 {
	return com.StrTo(ctx.Params(name)).MustInt64()
}

// GetFile returns information about user upload file by given form field name.
func (ctx *Context) GetFile(name string) (multipart.File, *multipart.FileHeader, error) {
	return ctx.Req.FormFile(name)
}

// SetCookie sets given cookie value to response header.
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
	cookie := http.Cookie{}
	cookie.Name = name
	cookie.Value = url.QueryEscape(value)

	if len(others) > 0 {
		switch v := others[0].(type) {
		case int:
			cookie.MaxAge = v
		case int64:
			cookie.MaxAge = int(v)
		case int32:
			cookie.MaxAge = int(v)
		}
	}

	// default "/"
	if len(others) > 1 {
		if v, ok := others[1].(string); ok && len(v) > 0 {
			cookie.Path = v
		}
	} else {
		cookie.Path = "/"
	}

	// default empty
	if len(others) > 2 {
		if v, ok := others[2].(string); ok && len(v) > 0 {
			cookie.Domain = v
		}
	}

	// default empty
	if len(others) > 3 {
		switch v := others[3].(type) {
		case bool:
			cookie.Secure = v
		default:
			if others[3] != nil {
				cookie.Secure = true
			}
		}
	}

	// default false. for session cookie default true
	if len(others) > 4 {
		if v, ok := others[4].(bool); ok && v {
			cookie.HttpOnly = true
		}
	}

	ctx.Resp.Header().Add("Set-Cookie", cookie.String())
}

// GetCookie returns given cookie value from request header.
func (ctx *Context) GetCookie(name string) string {
	cookie, err := ctx.Req.Cookie(name)
	if err != nil {
		return ""
	}
	return cookie.Value
}

// GetCookieInt returns cookie result in int type.
func (ctx *Context) GetCookieInt(name string) int {
	return com.StrTo(ctx.GetCookie(name)).MustInt()
}

// GetCookieInt64 returns cookie result in int64 type.
func (ctx *Context) GetCookieInt64(name string) int64 {
	return com.StrTo(ctx.GetCookie(name)).MustInt64()
}

var defaultCookieSecret string

// SetDefaultCookieSecret sets global default secure cookie secret.
func (m *Macaron) SetDefaultCookieSecret(secret string) {
	defaultCookieSecret = secret
}

// SetSecureCookie sets given cookie value to response header with default secret string.
func (ctx *Context) SetSecureCookie(name, value string, others ...interface{}) {
	ctx.SetSuperSecureCookie(defaultCookieSecret, name, value, others...)
}

// GetSecureCookie returns given cookie value from request header with default secret string.
func (ctx *Context) GetSecureCookie(key string) (string, bool) {
	return ctx.GetSuperSecureCookie(defaultCookieSecret, key)
}

// SetSuperSecureCookie sets given cookie value to response header with secret string.
func (ctx *Context) SetSuperSecureCookie(secret, name, value string, others ...interface{}) {
	m := md5.Sum([]byte(secret))
	secret = hex.EncodeToString(m[:])
	text, err := com.AESEncrypt([]byte(secret), []byte(value))
	if err != nil {
		panic("error encrypting cookie: " + err.Error())
	}
	ctx.SetCookie(name, hex.EncodeToString(text), others...)
}

// GetSuperSecureCookie returns given cookie value from request header with secret string.
func (ctx *Context) GetSuperSecureCookie(secret, key string) (string, bool) {
	val := ctx.GetCookie(key)
	if val == "" {
		return "", false
	}

	data, err := hex.DecodeString(val)
	if err != nil {
		return "", false
	}

	m := md5.Sum([]byte(secret))
	secret = hex.EncodeToString(m[:])
	text, err := com.AESDecrypt([]byte(secret), data)
	return string(text), err == nil
}

// ServeContent serves given content to response.
func (ctx *Context) ServeContent(name string, r io.ReadSeeker, params ...interface{}) {
	modtime := time.Now()
	for _, p := range params {
		switch v := p.(type) {
		case time.Time:
			modtime = v
		}
	}
	ctx.Resp.Header().Set("Content-Description", "Raw content")
	ctx.Resp.Header().Set("Content-Type", "text/plain")
	ctx.Resp.Header().Set("Expires", "0")
	ctx.Resp.Header().Set("Cache-Control", "must-revalidate")
	ctx.Resp.Header().Set("Pragma", "public")
	http.ServeContent(ctx.Resp, ctx.Req.Request, name, modtime, r)
}

// ServeFile serves given file to response.
func (ctx *Context) ServeFile(file string, names ...string) {
	var name string
	if len(names) > 0 {
		name = names[0]
	} else {
		name = path.Base(file)
	}
	ctx.Resp.Header().Set("Content-Description", "File Transfer")
	ctx.Resp.Header().Set("Content-Type", "application/octet-stream")
	ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+name)
	ctx.Resp.Header().Set("Content-Transfer-Encoding", "binary")
	ctx.Resp.Header().Set("Expires", "0")
	ctx.Resp.Header().Set("Cache-Control", "must-revalidate")
	ctx.Resp.Header().Set("Pragma", "public")
	http.ServeFile(ctx.Resp, ctx.Req.Request, file)
}

// ChangeStaticPath changes static path from old to new one.
func (ctx *Context) ChangeStaticPath(oldPath, newPath string) {
	if !filepath.IsAbs(oldPath) {
		oldPath = filepath.Join(Root, oldPath)
	}
	dir := statics.Get(oldPath)
	if dir != nil {
		statics.Delete(oldPath)

		if !filepath.IsAbs(newPath) {
			newPath = filepath.Join(Root, newPath)
		}
		*dir = http.Dir(newPath)
		statics.Set(dir)
	}
}
<|endoftext|>


<commit_before>package lion

import "golang.org/x/net/context"

// Check Context implements net.Context
var _ context.Context = (*Context)(nil)

// type ContextI interface {
// 	context.Context
// 	Param(string) string
// }

// Context implements golang.org/x/net/context.Context and stores values of url parameters
type Context struct {
	context.Context
	parent context.Context

	keys   []string
	values []string
}

// NewContext creates a new context instance
func NewContext() *Context {
	return NewContextWithParent(context.Background())
}

// NewContextWithParent creates a new context with a parent context specified
func NewContextWithParent(c context.Context) *Context {
	return &Context{
		parent: c,
	}
}

// Value returns the value for the passed key. If it is not found in the url params it returns parent's context Value
func (p *Context) Value(key interface{}) interface{} {
	if k, ok := key.(string); ok {
		if val, exist := p.ParamOk(k); exist {
			return val
		}
	}

	return p.parent.Value(key)
}

func (p *Context) addParam(key, val string) {
	p.keys = append(p.keys, key)
	p.values = append(p.values, val)
}

// Param returns the value of a param
func (p *Context) Param(key string) string {
	val, _ := p.ParamOk(key)
	return val
}

func (p *Context) ParamOk(key string) (string, bool) {
	for i, name := range p.keys {
		if name == key {
			return p.values[i], true
		}
	}
	return "", false
}

func (p *Context) reset() {
	p.keys = p.keys[:0]
	p.values = p.values[:0]
	p.parent = nil
}

// C returns a Context based on a context.Context passed. If it does not convert to Context, it creates a new one with the context passed as argument.
func C(c context.Context) *Context {
	if ctx, ok := c.(*Context); ok {
		return ctx
	}
	return NewContextWithParent(c)
}

// Param returns the value of a url param base on the passed context
func Param(c context.Context, key string) string {
	return C(c).Param(key)
}
<commit_msg>Docs for Context.ParamOk()<commit_after>package lion

import "golang.org/x/net/context"

// Check Context implements net.Context
var _ context.Context = (*Context)(nil)

// type ContextI interface {
// 	context.Context
// 	Param(string) string
// }

// Context implements golang.org/x/net/context.Context and stores values of url parameters
type Context struct {
	context.Context
	parent context.Context

	keys   []string
	values []string
}

// NewContext creates a new context instance
func NewContext() *Context {
	return NewContextWithParent(context.Background())
}

// NewContextWithParent creates a new context with a parent context specified
func NewContextWithParent(c context.Context) *Context {
	return &Context{
		parent: c,
	}
}

// Value returns the value for the passed key. If it is not found in the url params it returns parent's context Value
func (p *Context) Value(key interface{}) interface{} {
	if k, ok := key.(string); ok {
		if val, exist := p.ParamOk(k); exist {
			return val
		}
	}

	return p.parent.Value(key)
}

func (p *Context) addParam(key, val string) {
	p.keys = append(p.keys, key)
	p.values = append(p.values, val)
}

// Param returns the value of a param.
// If it does not exist it returns an empty string
func (p *Context) Param(key string) string {
	val, _ := p.ParamOk(key)
	return val
}

// ParamOk returns the value of a param and a boolean that indicates if the param exists.
func (p *Context) ParamOk(key string) (string, bool) {
	for i, name := range p.keys {
		if name == key {
			return p.values[i], true
		}
	}
	return "", false
}

func (p *Context) reset() {
	p.keys = p.keys[:0]
	p.values = p.values[:0]
	p.parent = nil
}

// C returns a Context based on a context.Context passed. If it does not convert to Context, it creates a new one with the context passed as argument.
func C(c context.Context) *Context {
	if ctx, ok := c.(*Context); ok {
		return ctx
	}
	return NewContextWithParent(c)
}

// Param returns the value of a url param base on the passed context
func Param(c context.Context, key string) string {
	return C(c).Param(key)
}
<|endoftext|>


<commit_before>package mego

import (
	"net/http"
	"strconv"
	"strings"
	"net/url"
	"mime/multipart"
	"mime"
)

// Context the mego context struct
type Context struct {
	req       *http.Request
	res       http.ResponseWriter
	routeData map[string]string
	ended     bool
	items     map[string]interface{}
}

// Request get the mego request
func (ctx *Context) Request() *http.Request {
	return ctx.req
}

// Response get the mego response
func (ctx *Context) Response() http.ResponseWriter {
	return ctx.res
}

// RouteString get the route parameter value as string by key
func (ctx *Context) RouteString(key string) string {
	if ctx.routeData == nil {
		return ""
	}
	return ctx.routeData[key]
}

// RouteInt get the route parameter value as int64 by key
func (ctx *Context) RouteInt(key string) int64 {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 {
		return 0
	}
	value,err := strconv.ParseInt(rawValue, 0, 64)
	if err != nil {
		return 0
	}
	return value
}

// RouteUint get the route parameter value as uint64 by key
func (ctx *Context) RouteUint(key string) uint64 {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 {
		return 0
	}
	value,err := strconv.ParseUint(rawValue, 0, 64)
	if err != nil {
		return 0
	}
	return value
}

// RouteFloat get the route parameter value as float by key
func (ctx *Context) RouteFloat(key string) float64 {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 {
		return 0
	}
	value,err := strconv.ParseFloat(rawValue, 64)
	if err != nil {
		return 0
	}
	return value
}

// RouteBool get the route parameter value as boolean by key
func (ctx *Context) RouteBool(key string) bool {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 || strings.ToLower(rawValue) == "false" || rawValue == "0"  {
		return false
	}
	return true
}

func (ctx *Context) PostFile(formName string) *PostFile {
	f, h, err := ctx.Request().FormFile(formName)
	if err != nil {
		return &PostFile{Error: err}
	}
	if f == nil {
		return nil
	}
	return &PostFile{FileName: h.Filename, Size: h.Size, File: f, Header: h}
}

// SetItem add context data to mego context
func (ctx *Context) SetItem(key string, data interface{}) {
	if len(key) == 0 {
		return
	}
	if ctx.items == nil {
		ctx.items = make(map[string]interface{})
	}
	ctx.items[key] = data
}

// GetItem get the context data from mego context by key
func (ctx *Context) GetItem(key string) interface{} {
	if ctx.items == nil {
		return nil
	}
	return ctx.items[key]
}

// RemoveItem delete context item from mego context by key
func (ctx *Context) RemoveItem(key string) interface{} {
	if ctx.items == nil {
		return nil
	}
	data := ctx.items[key]
	delete(ctx.items, key)
	return data
}

// End end the mego context and stop the rest request function
func (ctx *Context) End() {
	ctx.ended = true
}

// ParseForm parse the post form (both multipart and normal form)
func (ctx *Context) parseForm() error {
	if ctx.req.Method != "POST" && ctx.req.Method != "PUT" && ctx.req.Method != "PATCH" {
		return nil
	}
	isMultipart, reader, err := ctx.multipart()
	if err != nil {
		return err
	}
	if isMultipart {
		if ctx.req.MultipartForm != nil {
			return nil
		}
		if ctx.req.Form == nil {
			if err = ctx.req.ParseForm(); err != nil {
				return err
			}
		}
		f,err := reader.ReadForm(server.maxFormSize)
		if err != nil {
			return err
		}
		if ctx.req.PostForm == nil {
			ctx.req.PostForm = make(url.Values)
		}
		for k, v := range f.Value {
			ctx.req.Form[k] = append(ctx.req.Form[k], v...)
			// r.PostForm should also be populated. See Issue 9305.
			ctx.req.PostForm[k] = append(ctx.req.PostForm[k], v...)
		}
		ctx.req.MultipartForm = f
	} else {
		return ctx.req.ParseForm()
	}
	return nil
}

func (ctx *Context) multipart() (bool,*multipart.Reader,error) {
	v := ctx.req.Header.Get("Content-Type")
	if v == "" {
		return false, nil, nil
	}
	d, params, err := mime.ParseMediaType(v)
	if err != nil || d != "multipart/form-data" {
		return false, nil, nil
	}
	boundary, ok := params["boundary"]
	if !ok {
		return true, nil, http.ErrMissingBoundary
	}
	return true, multipart.NewReader(ctx.req.Body, boundary), nil
}<commit_msg>1. add UUID support 2. fix file upload size issue<commit_after>package mego

import (
	"net/http"
	"strconv"
	"strings"
	"net/url"
	"mime/multipart"
	"mime"
	"github.com/google/uuid"
)

type sizer interface {
	Size() int64
}

// Context the mego context struct
type Context struct {
	req       *http.Request
	res       http.ResponseWriter
	routeData map[string]string
	ended     bool
	items     map[string]interface{}
}

// Request get the mego request
func (ctx *Context) Request() *http.Request {
	return ctx.req
}

// Response get the mego response
func (ctx *Context) Response() http.ResponseWriter {
	return ctx.res
}

// RouteString get the route parameter value as string by key
func (ctx *Context) RouteString(key string) string {
	if ctx.routeData == nil {
		return ""
	}
	return ctx.routeData[key]
}

// RouteInt get the route parameter value as int64 by key
func (ctx *Context) RouteInt(key string) int64 {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 {
		return 0
	}
	value,err := strconv.ParseInt(rawValue, 0, 64)
	if err != nil {
		return 0
	}
	return value
}

// RouteUint get the route parameter value as uint64 by key
func (ctx *Context) RouteUint(key string) uint64 {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 {
		return 0
	}
	value,err := strconv.ParseUint(rawValue, 0, 64)
	if err != nil {
		return 0
	}
	return value
}

// RouteFloat get the route parameter value as float by key
func (ctx *Context) RouteFloat(key string) float64 {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 {
		return 0
	}
	value,err := strconv.ParseFloat(rawValue, 64)
	if err != nil {
		return 0
	}
	return value
}

func (ctx *Context) RouteUUID(key string) uuid.UUID {
	var rawValue= ctx.RouteString(key)
	if len(rawValue) == 0 {
		return uuid.Nil
	}
	value, err := uuid.Parse(rawValue)
	if err != nil {
		return uuid.Nil
	}
	return value
}

// RouteBool get the route parameter value as boolean by key
func (ctx *Context) RouteBool(key string) bool {
	var rawValue = ctx.RouteString(key)
	if len(rawValue) == 0 || strings.ToLower(rawValue) == "false" || rawValue == "0"  {
		return false
	}
	return true
}

func (ctx *Context) PostFile(formName string) *PostFile {
	f, h, err := ctx.Request().FormFile(formName)
	if err != nil {
		return &PostFile{Error: err}
	}
	if f == nil {
		return nil
	}
	var size int64
	if s, ok := f.(sizer); ok {
		size = s.Size()
	} else {
		size = 0
	}
	return &PostFile{FileName: h.Filename, Size: size, File: f, Header: h}
}

// SetItem add context data to mego context
func (ctx *Context) SetItem(key string, data interface{}) {
	if len(key) == 0 {
		return
	}
	if ctx.items == nil {
		ctx.items = make(map[string]interface{})
	}
	ctx.items[key] = data
}

// GetItem get the context data from mego context by key
func (ctx *Context) GetItem(key string) interface{} {
	if ctx.items == nil {
		return nil
	}
	return ctx.items[key]
}

// RemoveItem delete context item from mego context by key
func (ctx *Context) RemoveItem(key string) interface{} {
	if ctx.items == nil {
		return nil
	}
	data := ctx.items[key]
	delete(ctx.items, key)
	return data
}

// End end the mego context and stop the rest request function
func (ctx *Context) End() {
	ctx.ended = true
}

// ParseForm parse the post form (both multipart and normal form)
func (ctx *Context) parseForm() error {
	if ctx.req.Method != "POST" && ctx.req.Method != "PUT" && ctx.req.Method != "PATCH" {
		return nil
	}
	isMultipart, reader, err := ctx.multipart()
	if err != nil {
		return err
	}
	if isMultipart {
		if ctx.req.MultipartForm != nil {
			return nil
		}
		if ctx.req.Form == nil {
			if err = ctx.req.ParseForm(); err != nil {
				return err
			}
		}
		f,err := reader.ReadForm(server.maxFormSize)
		if err != nil {
			return err
		}
		if ctx.req.PostForm == nil {
			ctx.req.PostForm = make(url.Values)
		}
		for k, v := range f.Value {
			ctx.req.Form[k] = append(ctx.req.Form[k], v...)
			// r.PostForm should also be populated. See Issue 9305.
			ctx.req.PostForm[k] = append(ctx.req.PostForm[k], v...)
		}
		ctx.req.MultipartForm = f
	} else {
		return ctx.req.ParseForm()
	}
	return nil
}

func (ctx *Context) multipart() (bool,*multipart.Reader,error) {
	v := ctx.req.Header.Get("Content-Type")
	if v == "" {
		return false, nil, nil
	}
	d, params, err := mime.ParseMediaType(v)
	if err != nil || d != "multipart/form-data" {
		return false, nil, nil
	}
	boundary, ok := params["boundary"]
	if !ok {
		return true, nil, http.ErrMissingBoundary
	}
	return true, multipart.NewReader(ctx.req.Body, boundary), nil
}<|endoftext|>


<commit_before>package widget

import (
	"fmt"
	"html/template"
	"reflect"

	"github.com/jinzhu/gorm"
	"github.com/qor/qor/utils"
)

// Context widget context
type Context struct {
	Widgets          *Widgets
	DB               *gorm.DB
	AvailableWidgets []string
	Options          map[string]interface{}
	InlineEdit       bool
	FuncMaps         template.FuncMap
}

// Get get option with name
func (context Context) Get(name string) (interface{}, bool) {
	if value, ok := context.Options[name]; ok {
		return value, true
	}

	return nil, false
}

// Set set option by name
func (context *Context) Set(name string, value interface{}) {
	if context.Options == nil {
		context.Options = map[string]interface{}{}
	}
	context.Options[name] = value
}

// GetDB set option by name
func (context *Context) GetDB() *gorm.DB {
	if context.DB != nil {
		return context.DB
	}
	return context.Widgets.Config.DB
}

// Render render widget based on context
func (context *Context) Render(widgetName string, widgetGroupName string) template.HTML {
	var (
		visibleScopes         []string
		widgets               = context.Widgets
		widgetSettingResource = widgets.WidgetSettingResource
	)

	for _, scope := range registeredScopes {
		if scope.Visible(context) {
			visibleScopes = append(visibleScopes, scope.ToParam())
		}
	}

	if setting := context.findWidgetSetting(widgetName, append(visibleScopes, "default"), widgetGroupName); setting != nil {
		var (
			prefix        = widgetSettingResource.GetAdmin().GetRouter().Prefix
			widgetObj     = GetWidget(setting.GetSerializableArgumentKind())
			widgetSetting = widgetObj.Context(context, setting.GetSerializableArgument(setting))
			inlineEditURL = fmt.Sprintf("%v/%v/%v/edit?widget_scope=%v", prefix, widgetSettingResource.ToParam(), setting.GetWidgetName(), setting.GetScope())
		)

		if context.InlineEdit {
			prefix := widgets.Resource.GetAdmin().GetRouter().Prefix

			return template.HTML(fmt.Sprintf(
				"
\n%v\n
",
				prefix,
				prefix,
				utils.ToParamString(widgetObj.Name),
				fmt.Sprintf("%v/%v/inline-edit", prefix, widgets.Resource.ToParam()),
				inlineEditURL,
				widgetObj.Render(widgetSetting, setting.GetTemplate()),
			))
		}

		return widgetObj.Render(widgetSetting, setting.GetTemplate())
	}

	return template.HTML("")
}

func (context *Context) findWidgetSetting(widgetName string, scopes []string, widgetGroupName string) QorWidgetSettingInterface {
	var (
		db                    = context.GetDB()
		widgetSettingResource = context.Widgets.WidgetSettingResource
		setting               QorWidgetSettingInterface
		settings              = widgetSettingResource.NewSlice()
	)

	db.Where("name = ? AND scope IN (?)", widgetName, scopes).Order("activated_at DESC").Find(settings)

	settingsValue := reflect.Indirect(reflect.ValueOf(settings))
	if settingsValue.Len() > 0 {
	OUTTER:
		for _, scope := range scopes {
			for i := 0; i < settingsValue.Len(); i++ {
				s := settingsValue.Index(i).Interface().(QorWidgetSettingInterface)
				if s.GetScope() == scope {
					setting = s
					break OUTTER
				}
			}
		}
	}

	if setting == nil {
		if widgetGroupName == "" {
			utils.ExitWithMsg("Widget: Can't Create Widget Without Widget Type")
			return nil
		}
		setting = widgetSettingResource.NewStruct().(QorWidgetSettingInterface)
		setting.SetWidgetName(widgetName)
		setting.SetGroupName(widgetGroupName)
		setting.SetSerializableArgumentKind(widgetGroupName)
		db.Create(setting)
	} else if setting.GetGroupName() != widgetGroupName {
		setting.SetGroupName(widgetGroupName)
		db.Save(setting)
	}

	return setting
}
<commit_msg>Add widget setting to context<commit_after>package widget

import (
	"fmt"
	"html/template"
	"reflect"

	"github.com/jinzhu/gorm"
	"github.com/qor/qor/utils"
)

// Context widget context
type Context struct {
	Widgets          *Widgets
	DB               *gorm.DB
	AvailableWidgets []string
	Options          map[string]interface{}
	InlineEdit       bool
	FuncMaps         template.FuncMap
	WidgetSetting    QorWidgetSettingInterface
}

// Get get option with name
func (context Context) Get(name string) (interface{}, bool) {
	if value, ok := context.Options[name]; ok {
		return value, true
	}

	return nil, false
}

// Set set option by name
func (context *Context) Set(name string, value interface{}) {
	if context.Options == nil {
		context.Options = map[string]interface{}{}
	}
	context.Options[name] = value
}

// GetDB set option by name
func (context *Context) GetDB() *gorm.DB {
	if context.DB != nil {
		return context.DB
	}
	return context.Widgets.Config.DB
}

func (context *Context) Clone() *Context {
	return &Context{
		Widgets:          context.Widgets,
		DB:               context.DB,
		AvailableWidgets: context.AvailableWidgets,
		Options:          context.Options,
		InlineEdit:       context.InlineEdit,
		FuncMaps:         context.FuncMaps,
		WidgetSetting:    context.WidgetSetting,
	}
}

// Render render widget based on context
func (context *Context) Render(widgetName string, widgetGroupName string) template.HTML {
	var (
		visibleScopes         []string
		widgets               = context.Widgets
		widgetSettingResource = widgets.WidgetSettingResource
		clone                 = context.Clone()
	)

	for _, scope := range registeredScopes {
		if scope.Visible(context) {
			visibleScopes = append(visibleScopes, scope.ToParam())
		}
	}

	if setting := context.findWidgetSetting(widgetName, append(visibleScopes, "default"), widgetGroupName); setting != nil {
		clone.WidgetSetting = setting

		var (
			prefix        = widgetSettingResource.GetAdmin().GetRouter().Prefix
			widgetObj     = GetWidget(setting.GetSerializableArgumentKind())
			widgetSetting = widgetObj.Context(clone, setting.GetSerializableArgument(setting))
			inlineEditURL = fmt.Sprintf("%v/%v/%v/edit?widget_scope=%v", prefix, widgetSettingResource.ToParam(), setting.GetWidgetName(), setting.GetScope())
		)

		if clone.InlineEdit {
			prefix := widgets.Resource.GetAdmin().GetRouter().Prefix

			return template.HTML(fmt.Sprintf(
				"
\n%v\n
",
				prefix,
				prefix,
				utils.ToParamString(widgetObj.Name),
				fmt.Sprintf("%v/%v/inline-edit", prefix, widgets.Resource.ToParam()),
				inlineEditURL,
				widgetObj.Render(widgetSetting, setting.GetTemplate()),
			))
		}

		return widgetObj.Render(widgetSetting, setting.GetTemplate())
	}

	return template.HTML("")
}

func (context *Context) findWidgetSetting(widgetName string, scopes []string, widgetGroupName string) QorWidgetSettingInterface {
	var (
		db                    = context.GetDB()
		widgetSettingResource = context.Widgets.WidgetSettingResource
		setting               QorWidgetSettingInterface
		settings              = widgetSettingResource.NewSlice()
	)

	db.Where("name = ? AND scope IN (?)", widgetName, scopes).Order("activated_at DESC").Find(settings)

	settingsValue := reflect.Indirect(reflect.ValueOf(settings))
	if settingsValue.Len() > 0 {
	OUTTER:
		for _, scope := range scopes {
			for i := 0; i < settingsValue.Len(); i++ {
				s := settingsValue.Index(i).Interface().(QorWidgetSettingInterface)
				if s.GetScope() == scope {
					setting = s
					break OUTTER
				}
			}
		}
	}

	if setting == nil {
		if widgetGroupName == "" {
			utils.ExitWithMsg("Widget: Can't Create Widget Without Widget Type")
			return nil
		}
		setting = widgetSettingResource.NewStruct().(QorWidgetSettingInterface)
		setting.SetWidgetName(widgetName)
		setting.SetGroupName(widgetGroupName)
		setting.SetSerializableArgumentKind(widgetGroupName)
		db.Create(setting)
	} else if setting.GetGroupName() != widgetGroupName {
		setting.SetGroupName(widgetGroupName)
		db.Save(setting)
	}

	return setting
}
<|endoftext|>


<commit_before>// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dep

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

	"github.com/Masterminds/vcs"
	"github.com/pkg/errors"
	"github.com/sdboyer/gps"
)

// Ctx defines the supporting context of the tool.
type Ctx struct {
	GOPATH  string   // Selected Go path
	GOPATHS []string // Other Go paths
}

// NewContext creates a struct with the project's GOPATH. It assumes
// that of your "GOPATH"'s we want the one we are currently in.
func NewContext() (*Ctx, error) {
	// this way we get the default GOPATH that was added in 1.8
	buildContext := build.Default
	wd, err := os.Getwd()

	if err != nil {
		return nil, errors.Wrap(err, "getting work directory")
	}
	wd = filepath.FromSlash(wd)
	ctx := &Ctx{}

	for _, gp := range filepath.SplitList(buildContext.GOPATH) {
		gp = filepath.FromSlash(gp)

		if filepath.HasPrefix(wd, gp) {
			ctx.GOPATH = gp
		}

		ctx.GOPATHS = append(ctx.GOPATHS, gp)
	}

	if ctx.GOPATH == "" {
		return nil, errors.New("project not in a GOPATH")
	}

	return ctx, nil
}

func (c *Ctx) SourceManager() (*gps.SourceMgr, error) {
	return gps.NewSourceManager(analyzer{}, filepath.Join(c.GOPATH, "pkg", "dep"))
}

// LoadProject takes a path and searches up the directory tree for
// a project root.  If an absolute path is given, the search begins in that
// directory.  If a relative or empty path is given, the search start is computed
// from the current working directory.  The search stops when a file with the
// name ManifestName (manifest.json, by default) is located.
//
// The Project contains the parsed manifest as well as a parsed lock file, if
// present.  The import path is calculated as the remaining path segment
// below Ctx.GOPATH/src.
func (c *Ctx) LoadProject(path string) (*Project, error) {
	var err error
	p := new(Project)

	if path != "" {
		path, err = filepath.Abs(path)
		if err != nil {
			return nil, err
		}
	}
	switch path {
	case "":
		p.AbsRoot, err = findProjectRootFromWD()
	default:
		p.AbsRoot, err = findProjectRoot(path)
	}

	if err != nil {
		return nil, err
	}

	// The path may lie within a symlinked directory, resolve the path
	// before moving forward
	p.AbsRoot, err = c.resolveProjectRoot(p.AbsRoot)
	if err != nil {
		return nil, errors.Wrapf(err, "resolve project root")
	}

	ip, err := c.SplitAbsoluteProjectRoot(p.AbsRoot)
	if err != nil {
		return nil, errors.Wrap(err, "split absolute project root")
	}
	p.ImportRoot = gps.ProjectRoot(ip)

	mp := filepath.Join(p.AbsRoot, ManifestName)
	mf, err := os.Open(mp)
	if err != nil {
		if os.IsNotExist(err) {
			// TODO: list possible solutions? (dep init, cd $project)
			return nil, fmt.Errorf("no %v found in project root %v", ManifestName, p.AbsRoot)
		}
		// Unable to read the manifest file
		return nil, err
	}
	defer mf.Close()

	p.Manifest, err = readManifest(mf)
	if err != nil {
		return nil, fmt.Errorf("error while parsing %s: %s", mp, err)
	}

	lp := filepath.Join(p.AbsRoot, LockName)
	lf, err := os.Open(lp)
	if err != nil {
		if os.IsNotExist(err) {
			// It's fine for the lock not to exist
			return p, nil
		}
		// But if a lock does exist and we can't open it, that's a problem
		return nil, fmt.Errorf("could not open %s: %s", lp, err)
	}
	defer lf.Close()

	p.Lock, err = readLock(lf)
	if err != nil {
		return nil, fmt.Errorf("error while parsing %s: %s", lp, err)
	}

	return p, nil
}

// resolveProjectRoot evaluates the root directory and does the following:
//
// If the passed path is a symlink outside GOPATH to a directory within a
// GOPATH, the resolved full real path is returned.
//
// If the passed path is a symlink within a GOPATH, we return an error.
//
// If the passed path isn't a symlink at all, we just pass through.
func (c *Ctx) resolveProjectRoot(path string) (string, error) {
	// Determine if this path is a Symlink
	l, err := os.Lstat(path)
	if err != nil {
		return "", errors.Wrap(err, "resolveProjectRoot")
	}

	// Pass through if not
	if l.Mode()&os.ModeSymlink == 0 {
		return path, nil
	}

	// Resolve path
	resolved, err := filepath.EvalSymlinks(path)
	if err != nil {
		return "", errors.Wrap(err, "resolveProjectRoot")
	}

	// Determine if the symlink is within and of the GOPATHs, in which case we're not
	// sure how to resolve it.
	for _, gp := range c.GOPATHS {
		if filepath.HasPrefix(path, gp) {
			return "", fmt.Errorf("''%s' is linked to another path within GOPATH", path)
		}
	}

	return resolved, nil
}

// SplitAbsoluteProjectRoot takes an absolute path and compares it against declared
// GOPATH(s) to determine what portion of the input path should be treated as an
// import path - as a project root.
//
// The second returned string indicates which GOPATH value was used.
func (c *Ctx) SplitAbsoluteProjectRoot(path string) (string, error) {
	srcprefix := filepath.Join(c.GOPATH, "src") + string(filepath.Separator)
	if filepath.HasPrefix(path, srcprefix) {
		// filepath.ToSlash because we're dealing with an import path now,
		// not an fs path
		return filepath.ToSlash(path[len(srcprefix):]), nil
	}

	return "", fmt.Errorf("%s not in any $GOPATH", path)
}

// absoluteProjectRoot determines the absolute path to the project root
// including the $GOPATH. This will not work with stdlib packages and the
// package directory needs to exist.
func (c *Ctx) absoluteProjectRoot(path string) (string, error) {
	posspath := filepath.Join(c.GOPATH, "src", path)
	dirOK, err := IsDir(posspath)
	if err != nil {
		return "", errors.Wrapf(err, "checking if %s is a directory", posspath)
	}
	if !dirOK {
		return "", fmt.Errorf("%s does not exist", posspath)
	}
	return posspath, nil
}

func (c *Ctx) VersionInWorkspace(root gps.ProjectRoot) (gps.Version, error) {
	pr, err := c.absoluteProjectRoot(string(root))
	if err != nil {
		return nil, errors.Wrapf(err, "determine project root for %s", root)
	}

	repo, err := vcs.NewRepo("", pr)
	if err != nil {
		return nil, errors.Wrapf(err, "creating new repo for root: %s", pr)
	}

	ver, err := repo.Current()
	if err != nil {
		return nil, errors.Wrapf(err, "finding current branch/version for root: %s", pr)
	}

	rev, err := repo.Version()
	if err != nil {
		return nil, errors.Wrapf(err, "getting repo version for root: %s", pr)
	}

	// First look through tags.
	tags, err := repo.Tags()
	if err != nil {
		return nil, errors.Wrapf(err, "getting repo tags for root: %s", pr)
	}
	// Try to match the current version to a tag.
	if contains(tags, ver) {
		// Assume semver if it starts with a v.
		if strings.HasPrefix(ver, "v") {
			return gps.NewVersion(ver).Is(gps.Revision(rev)), nil
		}

		return nil, fmt.Errorf("version for root %s does not start with a v: %q", pr, ver)
	}

	// Look for the current branch.
	branches, err := repo.Branches()
	if err != nil {
		return nil, errors.Wrapf(err, "getting repo branch for root: %s")
	}
	// Try to match the current version to a branch.
	if contains(branches, ver) {
		return gps.NewBranch(ver).Is(gps.Revision(rev)), nil
	}

	return gps.Revision(rev), nil
}

// contains checks if a array of strings contains a value
func contains(a []string, b string) bool {
	for _, v := range a {
		if b == v {
			return true
		}
	}
	return false
}
<commit_msg>clearer error message<commit_after>// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dep

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

	"github.com/Masterminds/vcs"
	"github.com/pkg/errors"
	"github.com/sdboyer/gps"
)

// Ctx defines the supporting context of the tool.
type Ctx struct {
	GOPATH  string   // Selected Go path
	GOPATHS []string // Other Go paths
}

// NewContext creates a struct with the project's GOPATH. It assumes
// that of your "GOPATH"'s we want the one we are currently in.
func NewContext() (*Ctx, error) {
	// this way we get the default GOPATH that was added in 1.8
	buildContext := build.Default
	wd, err := os.Getwd()

	if err != nil {
		return nil, errors.Wrap(err, "getting work directory")
	}
	wd = filepath.FromSlash(wd)
	ctx := &Ctx{}

	for _, gp := range filepath.SplitList(buildContext.GOPATH) {
		gp = filepath.FromSlash(gp)

		if filepath.HasPrefix(wd, gp) {
			ctx.GOPATH = gp
		}

		ctx.GOPATHS = append(ctx.GOPATHS, gp)
	}

	if ctx.GOPATH == "" {
		return nil, errors.New("project not in a GOPATH")
	}

	return ctx, nil
}

func (c *Ctx) SourceManager() (*gps.SourceMgr, error) {
	return gps.NewSourceManager(analyzer{}, filepath.Join(c.GOPATH, "pkg", "dep"))
}

// LoadProject takes a path and searches up the directory tree for
// a project root.  If an absolute path is given, the search begins in that
// directory.  If a relative or empty path is given, the search start is computed
// from the current working directory.  The search stops when a file with the
// name ManifestName (manifest.json, by default) is located.
//
// The Project contains the parsed manifest as well as a parsed lock file, if
// present.  The import path is calculated as the remaining path segment
// below Ctx.GOPATH/src.
func (c *Ctx) LoadProject(path string) (*Project, error) {
	var err error
	p := new(Project)

	if path != "" {
		path, err = filepath.Abs(path)
		if err != nil {
			return nil, err
		}
	}
	switch path {
	case "":
		p.AbsRoot, err = findProjectRootFromWD()
	default:
		p.AbsRoot, err = findProjectRoot(path)
	}

	if err != nil {
		return nil, err
	}

	// The path may lie within a symlinked directory, resolve the path
	// before moving forward
	p.AbsRoot, err = c.resolveProjectRoot(p.AbsRoot)
	if err != nil {
		return nil, errors.Wrapf(err, "resolve project root")
	}

	ip, err := c.SplitAbsoluteProjectRoot(p.AbsRoot)
	if err != nil {
		return nil, errors.Wrap(err, "split absolute project root")
	}
	p.ImportRoot = gps.ProjectRoot(ip)

	mp := filepath.Join(p.AbsRoot, ManifestName)
	mf, err := os.Open(mp)
	if err != nil {
		if os.IsNotExist(err) {
			// TODO: list possible solutions? (dep init, cd $project)
			return nil, fmt.Errorf("no %v found in project root %v", ManifestName, p.AbsRoot)
		}
		// Unable to read the manifest file
		return nil, err
	}
	defer mf.Close()

	p.Manifest, err = readManifest(mf)
	if err != nil {
		return nil, fmt.Errorf("error while parsing %s: %s", mp, err)
	}

	lp := filepath.Join(p.AbsRoot, LockName)
	lf, err := os.Open(lp)
	if err != nil {
		if os.IsNotExist(err) {
			// It's fine for the lock not to exist
			return p, nil
		}
		// But if a lock does exist and we can't open it, that's a problem
		return nil, fmt.Errorf("could not open %s: %s", lp, err)
	}
	defer lf.Close()

	p.Lock, err = readLock(lf)
	if err != nil {
		return nil, fmt.Errorf("error while parsing %s: %s", lp, err)
	}

	return p, nil
}

// resolveProjectRoot evaluates the root directory and does the following:
//
// If the passed path is a symlink outside GOPATH to a directory within a
// GOPATH, the resolved full real path is returned.
//
// If the passed path is a symlink within a GOPATH, we return an error.
//
// If the passed path isn't a symlink at all, we just pass through.
func (c *Ctx) resolveProjectRoot(path string) (string, error) {
	// Determine if this path is a Symlink
	l, err := os.Lstat(path)
	if err != nil {
		return "", errors.Wrap(err, "resolveProjectRoot")
	}

	// Pass through if not
	if l.Mode()&os.ModeSymlink == 0 {
		return path, nil
	}

	// Resolve path
	resolved, err := filepath.EvalSymlinks(path)
	if err != nil {
		return "", errors.Wrap(err, "resolveProjectRoot")
	}

	// Determine if the symlink is within any of the GOPATHs, in which case we're not
	// sure how to resolve it.
	for _, gp := range c.GOPATHS {
		if filepath.HasPrefix(path, gp) {
			return "", fmt.Errorf("''%s' is linked to another path within a GOPATH (%s)", path, gp)
		}
	}

	return resolved, nil
}

// SplitAbsoluteProjectRoot takes an absolute path and compares it against declared
// GOPATH(s) to determine what portion of the input path should be treated as an
// import path - as a project root.
//
// The second returned string indicates which GOPATH value was used.
func (c *Ctx) SplitAbsoluteProjectRoot(path string) (string, error) {
	srcprefix := filepath.Join(c.GOPATH, "src") + string(filepath.Separator)
	if filepath.HasPrefix(path, srcprefix) {
		// filepath.ToSlash because we're dealing with an import path now,
		// not an fs path
		return filepath.ToSlash(path[len(srcprefix):]), nil
	}

	return "", fmt.Errorf("%s not in any $GOPATH", path)
}

// absoluteProjectRoot determines the absolute path to the project root
// including the $GOPATH. This will not work with stdlib packages and the
// package directory needs to exist.
func (c *Ctx) absoluteProjectRoot(path string) (string, error) {
	posspath := filepath.Join(c.GOPATH, "src", path)
	dirOK, err := IsDir(posspath)
	if err != nil {
		return "", errors.Wrapf(err, "checking if %s is a directory", posspath)
	}
	if !dirOK {
		return "", fmt.Errorf("%s does not exist", posspath)
	}
	return posspath, nil
}

func (c *Ctx) VersionInWorkspace(root gps.ProjectRoot) (gps.Version, error) {
	pr, err := c.absoluteProjectRoot(string(root))
	if err != nil {
		return nil, errors.Wrapf(err, "determine project root for %s", root)
	}

	repo, err := vcs.NewRepo("", pr)
	if err != nil {
		return nil, errors.Wrapf(err, "creating new repo for root: %s", pr)
	}

	ver, err := repo.Current()
	if err != nil {
		return nil, errors.Wrapf(err, "finding current branch/version for root: %s", pr)
	}

	rev, err := repo.Version()
	if err != nil {
		return nil, errors.Wrapf(err, "getting repo version for root: %s", pr)
	}

	// First look through tags.
	tags, err := repo.Tags()
	if err != nil {
		return nil, errors.Wrapf(err, "getting repo tags for root: %s", pr)
	}
	// Try to match the current version to a tag.
	if contains(tags, ver) {
		// Assume semver if it starts with a v.
		if strings.HasPrefix(ver, "v") {
			return gps.NewVersion(ver).Is(gps.Revision(rev)), nil
		}

		return nil, fmt.Errorf("version for root %s does not start with a v: %q", pr, ver)
	}

	// Look for the current branch.
	branches, err := repo.Branches()
	if err != nil {
		return nil, errors.Wrapf(err, "getting repo branch for root: %s")
	}
	// Try to match the current version to a branch.
	if contains(branches, ver) {
		return gps.NewBranch(ver).Is(gps.Revision(rev)), nil
	}

	return gps.Revision(rev), nil
}

// contains checks if a array of strings contains a value
func contains(a []string, b string) bool {
	for _, v := range a {
		if b == v {
			return true
		}
	}
	return false
}
<|endoftext|>


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

package colly

import (
	"strings"

	"github.com/PuerkitoBio/goquery"
	"golang.org/x/net/html"
)

// HTMLElement is the representation of a HTML tag.
type HTMLElement struct {
	// Name is the name of the tag
	Name       string
	Text       string
	attributes []html.Attribute
	// Request is the request object of the element's HTML document
	Request *Request
	// Response is the Response object of the element's HTML document
	Response *Response
	// DOM is the goquery parsed DOM object of the page. DOM is relative
	// to the current HTMLElement
	DOM *goquery.Selection
}

// NewHTMLElementFromSelectionNode creates a HTMLElement from a goquery.Selection Node.
func NewHTMLElementFromSelectionNode(resp *Response, s *goquery.Selection, n *html.Node) *HTMLElement {
	return &HTMLElement{
		Name:       n.Data,
		Request:    resp.Request,
		Response:   resp,
		Text:       goquery.NewDocumentFromNode(n).Text(),
		DOM:        s,
		attributes: n.Attr,
	}
}

// Attr returns the selected attribute of a HTMLElement or empty string
// if no attribute found
func (h *HTMLElement) Attr(k string) string {
	for _, a := range h.attributes {
		if a.Key == k {
			return a.Val
		}
	}
	return ""
}

// ChildText returns the concatenated and stripped text content of the matching
// elements.
func (h *HTMLElement) ChildText(goquerySelector string) string {
	return strings.TrimSpace(h.DOM.Find(goquerySelector).Text())
}

// ChildAttr returns the stripped text content of the first matching
// element's attribute.
func (h *HTMLElement) ChildAttr(goquerySelector, attrName string) string {
	if attr, ok := h.DOM.Find(goquerySelector).Attr(attrName); ok {
		return strings.TrimSpace(attr)
	}
	return ""
}

// ChildAttrs returns the stripped text content of all the matching
// element's attributes.
func (h *HTMLElement) ChildAttrs(goquerySelector, attrName string) []string {
	var res []string
	h.DOM.Find(goquerySelector).Each(func(_ int, s *goquery.Selection) {
		if attr, ok := s.Attr(attrName); ok {
			res = append(res, strings.TrimSpace(attr))
		}
	})
	return res
}

// ForEach iterates over the elements matched by the first argument
// and calls the callback function on every HTMLElement match.
func (h *HTMLElement) ForEach(goquerySelector string, callback func(int, *HTMLElement)) {
	i := 0
	h.DOM.Find(goquerySelector).Each(func(_ int, s *goquery.Selection) {
		for _, n := range s.Nodes {
			callback(i, NewHTMLElementFromSelectionNode(h.Response, s, n))
			i++
		}
	})
}
<commit_msg>Add ForEachWithBreak function to HTMLElement<commit_after>// Copyright 2018 Adam Tauber
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package colly

import (
	"strings"

	"github.com/PuerkitoBio/goquery"
	"golang.org/x/net/html"
)

// HTMLElement is the representation of a HTML tag.
type HTMLElement struct {
	// Name is the name of the tag
	Name       string
	Text       string
	attributes []html.Attribute
	// Request is the request object of the element's HTML document
	Request *Request
	// Response is the Response object of the element's HTML document
	Response *Response
	// DOM is the goquery parsed DOM object of the page. DOM is relative
	// to the current HTMLElement
	DOM *goquery.Selection
}

// NewHTMLElementFromSelectionNode creates a HTMLElement from a goquery.Selection Node.
func NewHTMLElementFromSelectionNode(resp *Response, s *goquery.Selection, n *html.Node) *HTMLElement {
	return &HTMLElement{
		Name:       n.Data,
		Request:    resp.Request,
		Response:   resp,
		Text:       goquery.NewDocumentFromNode(n).Text(),
		DOM:        s,
		attributes: n.Attr,
	}
}

// Attr returns the selected attribute of a HTMLElement or empty string
// if no attribute found
func (h *HTMLElement) Attr(k string) string {
	for _, a := range h.attributes {
		if a.Key == k {
			return a.Val
		}
	}
	return ""
}

// ChildText returns the concatenated and stripped text content of the matching
// elements.
func (h *HTMLElement) ChildText(goquerySelector string) string {
	return strings.TrimSpace(h.DOM.Find(goquerySelector).Text())
}

// ChildAttr returns the stripped text content of the first matching
// element's attribute.
func (h *HTMLElement) ChildAttr(goquerySelector, attrName string) string {
	if attr, ok := h.DOM.Find(goquerySelector).Attr(attrName); ok {
		return strings.TrimSpace(attr)
	}
	return ""
}

// ChildAttrs returns the stripped text content of all the matching
// element's attributes.
func (h *HTMLElement) ChildAttrs(goquerySelector, attrName string) []string {
	var res []string
	h.DOM.Find(goquerySelector).Each(func(_ int, s *goquery.Selection) {
		if attr, ok := s.Attr(attrName); ok {
			res = append(res, strings.TrimSpace(attr))
		}
	})
	return res
}

// ForEach iterates over the elements matched by the first argument
// and calls the callback function on every HTMLElement match.
func (h *HTMLElement) ForEach(goquerySelector string, callback func(int, *HTMLElement)) {
	i := 0
	h.DOM.Find(goquerySelector).Each(func(_ int, s *goquery.Selection) {
		for _, n := range s.Nodes {
			callback(i, NewHTMLElementFromSelectionNode(h.Response, s, n))
			i++
		}
	})
}

// ForEach iterates over the elements matched by the first argument
// and calls the callback function on every HTMLElement match.
// It is identical to ForEach except that it is possible to break
// out of the loop by returning false in the callback function. It returns the
// current Selection object.
func (h *HTMLElement) ForEachWithBreak(goquerySelector string, callback func(int, *HTMLElement) bool) {
	i := 0
	h.DOM.Find(goquerySelector).EachWithBreak(func(_ int, s *goquery.Selection) bool {
		for _, n := range s.Nodes {
			if callback(i, NewHTMLElementFromSelectionNode(h.Response, s, n)) {
				return true
			}
			i++
		}
		return false
	})
}
<|endoftext|>


<commit_before>package clw11

/*
#cgo windows linux LDFLAGS: -lOpenCL
#cgo darwin LDFLAGS: -framework OpenCL

#ifdef __APPLE__
#include "OpenCL/opencl.h"
#else
#include "CL/opencl.h"
#endif

extern void contextCallback(char *errinfo, void *private_info, size_t cb, void *user_data);

void callContextCallback(const char *errinfo, const void *private_info, size_t cb, void *user_data)
{
	contextCallback((char*)errinfo, (void*)private_info, cb, user_data);
}
*/
import "C"
import "unsafe"

type (
	Context           C.cl_context
	ContextProperties C.cl_context_properties
)

const (
	ContextPlatform ContextProperties = C.CL_CONTEXT_PLATFORM
)

var contextCallbackCounter int // FIXME broken, copy event's implementation

func CreateContext(properties []ContextProperties, devices []DeviceID,
	callback func(err string, data []byte)) (Context, error) {

	var propertiesValue *C.cl_context_properties
	if properties != nil {
		properties = append(properties, 0)
		propertiesValue = (*C.cl_context_properties)(unsafe.Pointer(&properties[0]))
	}

	// FIXME broken, copy event's implementation
	var cCallbackFunction *[0]byte
	if callback != nil {
		contextCallbackMap[contextCallbackCounter] = callback
		contextCallbackCounter++
		cCallbackFunction = (*[0]byte)(C.callContextCallback)
	}

	var clErr C.cl_int
	context := Context(C.clCreateContext(propertiesValue, C.cl_uint(len(devices)),
		(*C.cl_device_id)(unsafe.Pointer(&devices[0])), cCallbackFunction,
		unsafe.Pointer(uintptr(contextCallbackCounter)), &clErr))

	// FIXME broken, copy event's implementation
	if err := toError(clErr); err != nil {
		if callback != nil {
			contextCallbackCounter--
			delete(contextCallbackMap, contextCallbackCounter)
		}
		return context, err
	}

	return context, nil
}
<commit_msg>Keeping variable names consistent.<commit_after>package clw11

/*
#cgo windows linux LDFLAGS: -lOpenCL
#cgo darwin LDFLAGS: -framework OpenCL

#ifdef __APPLE__
#include "OpenCL/opencl.h"
#else
#include "CL/opencl.h"
#endif

extern void contextCallback(char *errinfo, void *private_info, size_t cb, void *user_data);

void callContextCallback(const char *errinfo, const void *private_info, size_t cb, void *user_data)
{
	contextCallback((char*)errinfo, (void*)private_info, cb, user_data);
}
*/
import "C"
import "unsafe"

type (
	Context           C.cl_context
	ContextProperties C.cl_context_properties
)

const (
	ContextPlatform ContextProperties = C.CL_CONTEXT_PLATFORM
)

var contextCallbackCounter int // FIXME broken, copy event's implementation

func CreateContext(properties []ContextProperties, devices []DeviceID,
	callback func(err string, data []byte)) (Context, error) {

	var propertiesValue *C.cl_context_properties
	if properties != nil {
		properties = append(properties, 0)
		propertiesValue = (*C.cl_context_properties)(unsafe.Pointer(&properties[0]))
	}

	// FIXME broken, copy event's implementation
	var cCallbackFunction *[0]byte
	if callback != nil {
		contextCallbackMap[contextCallbackCounter] = callback
		contextCallbackCounter++
		cCallbackFunction = (*[0]byte)(C.callContextCallback)
	}

	var err C.cl_int
	context := Context(C.clCreateContext(propertiesValue, C.cl_uint(len(devices)),
		(*C.cl_device_id)(unsafe.Pointer(&devices[0])), cCallbackFunction,
		unsafe.Pointer(uintptr(contextCallbackCounter)), &err))

	// FIXME broken, copy event's implementation
	if err := toError(err); err != nil {
		if callback != nil {
			contextCallbackCounter--
			delete(contextCallbackMap, contextCallbackCounter)
		}
		return context, err
	}

	return context, nil
}
<|endoftext|>


<commit_before>package http

import (
	"context"
	"net"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"go.uber.org/zap"
)

// DefaultShutdownTimeout is the default timeout for shutting down the http server.
const DefaultShutdownTimeout = 20 * time.Second

// Server is an abstraction around the http.Server that handles a server process.
// It manages the full lifecycle of a server by serving a handler on a socket.
// If signals have been registered, it will attempt to terminate the server using
// Shutdown if a signal is received and will force a shutdown if a second signal
// is received.
type Server struct {
	ShutdownTimeout time.Duration

	srv     *http.Server
	signals map[os.Signal]struct{}
	logger  *zap.Logger
	wg      sync.WaitGroup
}

// NewServer returns a new server struct that can be used.
func NewServer(handler http.Handler, logger *zap.Logger) *Server {
	if logger == nil {
		logger = zap.NewNop()
	}
	return &Server{
		ShutdownTimeout: DefaultShutdownTimeout,
		srv: &http.Server{
			Handler: handler,
		},
		logger: logger,
	}
}

// Serve will run the server using the listener to accept connections.
func (s *Server) Serve(listener net.Listener) error {
	// When we return, wait for all pending goroutines to finish.
	defer s.wg.Wait()

	signalCh, cancel := s.notifyOnSignals()
	defer cancel()

	errCh := s.serve(listener)
	select {
	case err := <-errCh:
		// The server has failed and reported an error.
		return err
	case <-signalCh:
		// We have received an interrupt. Signal the shutdown process.
		return s.shutdown(signalCh)
	}
}

func (s *Server) serve(listener net.Listener) <-chan error {
	s.wg.Add(1)
	errCh := make(chan error, 1)
	go func() {
		defer s.wg.Done()
		if err := s.srv.Serve(listener); err != nil {
			errCh <- err
		}
		close(errCh)
	}()
	return errCh
}

func (s *Server) shutdown(signalCh <-chan os.Signal) error {
	s.logger.Info("Shutting down server", zap.Duration("timeout", s.ShutdownTimeout))

	// The shutdown needs to succeed in 20 seconds or less.
	ctx, cancel := context.WithTimeout(context.Background(), s.ShutdownTimeout)
	defer cancel()

	// Wait for another signal to cancel the shutdown.
	done := make(chan struct{})
	defer close(done)

	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		select {
		case <-signalCh:
			s.logger.Info("Initializing hard shutdown")
			cancel()
		case <-done:
		}
	}()
	return s.srv.Shutdown(ctx)
}

// ListenForSignals registers the the server to listen for the given signals
// to shutdown the server. The signals are not captured until Serve is called.
func (s *Server) ListenForSignals(signals ...os.Signal) {
	if s.signals == nil {
		s.signals = make(map[os.Signal]struct{})
	}

	for _, sig := range signals {
		s.signals[sig] = struct{}{}
	}
}

func (s *Server) notifyOnSignals() (_ <-chan os.Signal, cancel func()) {
	if len(s.signals) == 0 {
		return nil, func() {}
	}

	// Retrieve which signals we want to be notified on.
	signals := make([]os.Signal, 0, len(s.signals))
	for sig := range s.signals {
		signals = append(signals, sig)
	}

	// Create the signal channel and mark ourselves to be notified
	// of signals. Allow up to two signals for each signal type we catch.
	signalCh := make(chan os.Signal, len(signals)*2)
	signal.Notify(signalCh, signals...)
	return signalCh, func() { signal.Stop(signalCh) }
}

// ListenAndServe is a convenience method for opening a listener using the address
// and then serving the handler on that address. This method sets up the typical
// signal handlers.
func ListenAndServe(addr string, handler http.Handler, logger *zap.Logger) error {
	l, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	server := NewServer(handler, logger)
	server.ListenForSignals(os.Interrupt, syscall.SIGTERM)
	return server.Serve(l)
}
<commit_msg>fix(http): use a duration literal for the server's shutdown timeout<commit_after>package http

import (
	"context"
	"net"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/influxdata/influxdb/logger"
	"go.uber.org/zap"
)

// DefaultShutdownTimeout is the default timeout for shutting down the http server.
const DefaultShutdownTimeout = 20 * time.Second

// Server is an abstraction around the http.Server that handles a server process.
// It manages the full lifecycle of a server by serving a handler on a socket.
// If signals have been registered, it will attempt to terminate the server using
// Shutdown if a signal is received and will force a shutdown if a second signal
// is received.
type Server struct {
	ShutdownTimeout time.Duration

	srv     *http.Server
	signals map[os.Signal]struct{}
	logger  *zap.Logger
	wg      sync.WaitGroup
}

// NewServer returns a new server struct that can be used.
func NewServer(handler http.Handler, logger *zap.Logger) *Server {
	if logger == nil {
		logger = zap.NewNop()
	}
	return &Server{
		ShutdownTimeout: DefaultShutdownTimeout,
		srv: &http.Server{
			Handler: handler,
		},
		logger: logger,
	}
}

// Serve will run the server using the listener to accept connections.
func (s *Server) Serve(listener net.Listener) error {
	// When we return, wait for all pending goroutines to finish.
	defer s.wg.Wait()

	signalCh, cancel := s.notifyOnSignals()
	defer cancel()

	errCh := s.serve(listener)
	select {
	case err := <-errCh:
		// The server has failed and reported an error.
		return err
	case <-signalCh:
		// We have received an interrupt. Signal the shutdown process.
		return s.shutdown(signalCh)
	}
}

func (s *Server) serve(listener net.Listener) <-chan error {
	s.wg.Add(1)
	errCh := make(chan error, 1)
	go func() {
		defer s.wg.Done()
		if err := s.srv.Serve(listener); err != nil {
			errCh <- err
		}
		close(errCh)
	}()
	return errCh
}

func (s *Server) shutdown(signalCh <-chan os.Signal) error {
	s.logger.Info("Shutting down server", logger.DurationLiteral("timeout", s.ShutdownTimeout))

	// The shutdown needs to succeed in 20 seconds or less.
	ctx, cancel := context.WithTimeout(context.Background(), s.ShutdownTimeout)
	defer cancel()

	// Wait for another signal to cancel the shutdown.
	done := make(chan struct{})
	defer close(done)

	s.wg.Add(1)
	go func() {
		defer s.wg.Done()
		select {
		case <-signalCh:
			s.logger.Info("Initializing hard shutdown")
			cancel()
		case <-done:
		}
	}()
	return s.srv.Shutdown(ctx)
}

// ListenForSignals registers the the server to listen for the given signals
// to shutdown the server. The signals are not captured until Serve is called.
func (s *Server) ListenForSignals(signals ...os.Signal) {
	if s.signals == nil {
		s.signals = make(map[os.Signal]struct{})
	}

	for _, sig := range signals {
		s.signals[sig] = struct{}{}
	}
}

func (s *Server) notifyOnSignals() (_ <-chan os.Signal, cancel func()) {
	if len(s.signals) == 0 {
		return nil, func() {}
	}

	// Retrieve which signals we want to be notified on.
	signals := make([]os.Signal, 0, len(s.signals))
	for sig := range s.signals {
		signals = append(signals, sig)
	}

	// Create the signal channel and mark ourselves to be notified
	// of signals. Allow up to two signals for each signal type we catch.
	signalCh := make(chan os.Signal, len(signals)*2)
	signal.Notify(signalCh, signals...)
	return signalCh, func() { signal.Stop(signalCh) }
}

// ListenAndServe is a convenience method for opening a listener using the address
// and then serving the handler on that address. This method sets up the typical
// signal handlers.
func ListenAndServe(addr string, handler http.Handler, logger *zap.Logger) error {
	l, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	server := NewServer(handler, logger)
	server.ListenForSignals(os.Interrupt, syscall.SIGTERM)
	return server.Serve(l)
}
<|endoftext|>


<commit_before>package utee

import (
	"crypto/tls"
	"fmt"
	"golang.org/x/net/http2"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

const (
	MAX_HTTP_CLIENT_CONCURRENT = 1000
)

var (
	HttpClientThrottle = make(chan interface{}, MAX_HTTP_CLIENT_CONCURRENT)
	http2Client        = &http.Client{
		Transport: &http2.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}},
	}
)

func HttpPost(postUrl string, q url.Values, credential ...string) ([]byte, error) {
	return httpPost(1, postUrl, q, credential...)
}

func Http2Post(postUrl string, q url.Values, credential ...string) ([]byte, error) {
	return httpPost(2, postUrl, q, credential...)
}

func httpPost(v int, postUrl string, q url.Values, credential ...string) ([]byte, error) {
	HttpClientThrottle <- nil
	defer func() {
		<-HttpClientThrottle
	}()

	var resp *http.Response
	var err error
	req, err := http.NewRequest("POST", postUrl, strings.NewReader(q.Encode()))
	if err != nil {
		return nil, fmt.Errorf("[http] err %s, %s\n", postUrl, err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	if len(credential) == 2 {
		req.SetBasicAuth(credential[0], credential[1])
	}

	var client *http.Client
	if v == 1 {
		client = http.DefaultClient
	} else {
		client = http2Client
	}

	resp, err = client.Do(req)

	if err != nil {
		return nil, fmt.Errorf("[http] err %s, %s\n", postUrl, err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("[http] status err %s, %d\n", postUrl, resp.StatusCode)
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[http] read err %s, %s\n", postUrl, err)
	}
	return b, nil
}

func HttpGet(getUrl string, credential ...string) ([]byte, error) {
	return httpGet(1, getUrl, credential...)
}

func Http2Get(getUrl string, credential ...string) ([]byte, error) {
	return httpGet(1, getUrl, credential...)
}

func httpGet(v int, getUrl string, credential ...string) ([]byte, error) {
	HttpClientThrottle <- nil
	defer func() {
		<-HttpClientThrottle
	}()

	var resp *http.Response
	var err error
	req, err := http.NewRequest("GET", getUrl, nil)
	if err != nil {
		return nil, fmt.Errorf("[http] err %s, %s\n", getUrl, err)
	}
	if len(credential) == 2 {
		req.SetBasicAuth(credential[0], credential[1])
	}

	var client *http.Client
	if v == 1 {
		client = http.DefaultClient
	} else {
		client = http2Client
	}

	resp, err = client.Do(req)

	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("[http get] status err %s, %d\n", getUrl, resp.StatusCode)
	}
	return ioutil.ReadAll(resp.Body)
}
<commit_msg>http2Get param v should be 2<commit_after>package utee

import (
	"crypto/tls"
	"fmt"
	"golang.org/x/net/http2"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

const (
	MAX_HTTP_CLIENT_CONCURRENT = 1000
)

var (
	HttpClientThrottle = make(chan interface{}, MAX_HTTP_CLIENT_CONCURRENT)
	http2Client        = &http.Client{
		Transport: &http2.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}},
	}
)

func HttpPost(postUrl string, q url.Values, credential ...string) ([]byte, error) {
	return httpPost(1, postUrl, q, credential...)
}

func Http2Post(postUrl string, q url.Values, credential ...string) ([]byte, error) {
	return httpPost(2, postUrl, q, credential...)
}

func httpPost(v int, postUrl string, q url.Values, credential ...string) ([]byte, error) {
	HttpClientThrottle <- nil
	defer func() {
		<-HttpClientThrottle
	}()

	var resp *http.Response
	var err error
	req, err := http.NewRequest("POST", postUrl, strings.NewReader(q.Encode()))
	if err != nil {
		return nil, fmt.Errorf("[http] err %s, %s\n", postUrl, err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	if len(credential) == 2 {
		req.SetBasicAuth(credential[0], credential[1])
	}

	var client *http.Client
	if v == 1 {
		client = http.DefaultClient
	} else {
		client = http2Client
	}

	resp, err = client.Do(req)

	if err != nil {
		return nil, fmt.Errorf("[http] err %s, %s\n", postUrl, err)
	}
	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("[http] status err %s, %d\n", postUrl, resp.StatusCode)
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("[http] read err %s, %s\n", postUrl, err)
	}
	return b, nil
}

func HttpGet(getUrl string, credential ...string) ([]byte, error) {
	return httpGet(1, getUrl, credential...)
}

func Http2Get(getUrl string, credential ...string) ([]byte, error) {
	return httpGet(2, getUrl, credential...)
}

func httpGet(v int, getUrl string, credential ...string) ([]byte, error) {
	HttpClientThrottle <- nil
	defer func() {
		<-HttpClientThrottle
	}()

	var resp *http.Response
	var err error
	req, err := http.NewRequest("GET", getUrl, nil)
	if err != nil {
		return nil, fmt.Errorf("[http] err %s, %s\n", getUrl, err)
	}
	if len(credential) == 2 {
		req.SetBasicAuth(credential[0], credential[1])
	}

	var client *http.Client
	if v == 1 {
		client = http.DefaultClient
	} else {
		client = http2Client
	}

	resp, err = client.Do(req)

	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("[http get] status err %s, %d\n", getUrl, resp.StatusCode)
	}
	return ioutil.ReadAll(resp.Body)
}
<|endoftext|>


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

package dlshared

import (
	"fmt"
	"sync"
	"time"
	"net/http"
	"github.com/gorilla/mux"
)

type HttpServerHandlerDef struct {
	Path string
	HandlerFunc http.HandlerFunc
}

type HttpServer struct {
	router *mux.Router
	server *http.Server
	handlerDefs []*HttpServerHandlerDef
	kernel *Kernel
	Logger
	staticFileDir string
	bindAddress string
	port int16
}

func (self *HttpServer) Id() string {
	return "httpServer"
}

func (self *HttpServer) Stop(kernel *Kernel) error {
	return nil
}

func (self *HttpServer) Start(kernel *Kernel) error {

	// TODO: Add access logging

	self.Logger = kernel.Logger

	self.staticFileDir = kernel.Configuration.String("server.http.staticFileDir", "./static/")
	self.bindAddress = kernel.Configuration.String("server.http.bindAddress", "127.0.0.1")
	self.port = int16(kernel.Configuration.Int("server.http.port", 8080))

	self.kernel = kernel
	self.router = mux.NewRouter()

	if self.handlerDefs != nil {
		for _, handlerDef := range self.handlerDefs {
			self.router.HandleFunc(handlerDef.Path, handlerDef.HandlerFunc)
		}
	}

	self.router.PathPrefix("/").Handler(http.FileServer(http.Dir(self.staticFileDir)))

	http.Handle("/", self.router)

	self.server = &http.Server{
		Addr: AssembleHostnameAndPort(self.bindAddress, self.port),
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	var startWaitGroup sync.WaitGroup
	startWaitGroup.Add(1)

	go func() {
		startWaitGroup.Done()
		if err := self.server.ListenAndServe(); err != nil {
			panic(fmt.Sprintf("Error in listen and serve call - server unpredictable: %v", err))
		}
	}()

	// Wait for the goroutine to be allocated before moving on. This is a hack that does
	// no really solve the problem. Ideally, listen and serve would have a notification/callback
	// of some sort so that we know the server is initialized and running.
	startWaitGroup.Wait()

	return nil
}

func NewHttpServer(handlerDefs ...*HttpServerHandlerDef) *HttpServer {

	server := &HttpServer{ }

	if handlerDefs != nil {
		for _, def := range handlerDefs {
			server.handlerDefs = append(server.handlerDefs, def)
		}
	}

	return server
}

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

package dlshared

import (
	"fmt"
	"sync"
	"time"
	"net/http"
	"github.com/gorilla/mux"
)

type HttpServerHandlerDef struct {
	Path string
	HandlerFunc http.HandlerFunc
}

type HttpServer struct {
	router *mux.Router
	server *http.Server
	handlerDefs []*HttpServerHandlerDef
	kernel *Kernel
	Logger
	staticFileDir string
	bindAddress string
	port int16
}

func (self *HttpServer) Id() string {
	return "httpServer"
}

func (self *HttpServer) Stop(kernel *Kernel) error {
	return nil
}

func (self *HttpServer) Start(kernel *Kernel) error {

	fmt.Println("--------------- start is called")

	// TODO: Add access logging

	self.Logger = kernel.Logger

	self.staticFileDir = kernel.Configuration.String("server.http.staticFileDir", "./static/")
	self.bindAddress = kernel.Configuration.String("server.http.bindAddress", "127.0.0.1")
	self.port = int16(kernel.Configuration.Int("server.http.port", 8080))

	self.kernel = kernel
	self.router = mux.NewRouter()

	if self.handlerDefs != nil {
		for _, handlerDef := range self.handlerDefs {
			self.router.HandleFunc(handlerDef.Path, handlerDef.HandlerFunc)
		}
	}

	self.router.PathPrefix("/").Handler(http.FileServer(http.Dir(self.staticFileDir)))

	http.Handle("/", self.router)

	self.server = &http.Server{
		Addr: AssembleHostnameAndPort(self.bindAddress, self.port),
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	var startWaitGroup sync.WaitGroup
	startWaitGroup.Add(1)

	go func() {
		startWaitGroup.Done()
		if err := self.server.ListenAndServe(); err != nil {
			panic(fmt.Sprintf("Error in listen and serve call - server unpredictable: %v", err))
		}
	}()

	// Wait for the goroutine to be allocated before moving on. This is a hack that does
	// no really solve the problem. Ideally, listen and serve would have a notification/callback
	// of some sort so that we know the server is initialized and running.
	startWaitGroup.Wait()

	return nil
}

func NewHttpServer(handlerDefs ...*HttpServerHandlerDef) *HttpServer {

	server := &HttpServer{ }

	if handlerDefs != nil {
		for _, def := range handlerDefs {
			server.handlerDefs = append(server.handlerDefs, def)
		}
	}

	return server
}

<|endoftext|>