<commit_before>package account

import (
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"
	"strconv"

	"github.com/koding/bongo"
)

// lists followed channels of an account
func ListChannels(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {

	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	query := request.GetQuery(u)
	query = c.OverrideQuery(query)
	if query.AccountId == 0 {
		query.AccountId = accountId
	}

	if query.Type == "" {
		query.Type = models.Channel_TYPE_TOPIC
	}

	a := &models.Account{Id: accountId}
	channels, err := a.FetchChannels(query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	cc := models.NewChannelContainers()
	cc.PopulateWith(channels, query.AccountId).AddUnreadCount(query.AccountId)

	return response.HandleResultAndError(cc, cc.Err())
}

func GetAccountFromSession(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	if c.Client == nil || c.Client.Account == nil {
		return response.NewNotFound()
	}

	res := map[string]interface{}{
		"id":    strconv.FormatInt(c.Client.Account.Id, 10),
		"nick":  c.Client.Account.Nick,
		"token": c.Client.Account.Token,
	}
	return response.NewOK(res)
}

func ParticipatedChannelCount(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	query := request.GetQuery(u)
	query = c.OverrideQuery(query)

	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if query.Type == "" {
		query.Type = models.Channel_TYPE_TOPIC
	}
	cp := models.NewChannelParticipant()
	a := &models.Account{Id: accountId}

	return response.HandleResultAndError(cp.ParticipatedChannelCount(a, query))
}

func ListPosts(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	buildMessageQuery := query.Clone()

	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	// Get Group Channel
	selector := map[string]interface{}{
		"group_name":    query.GroupName,
		"type_constant": models.Channel_TYPE_GROUP,
	}

	c := models.NewChannel()
	if err := c.One(bongo.NewQS(selector)); err != nil {
		return response.NewBadRequest(err)
	}
	// fetch only channel messages
	query.Type = models.ChannelMessage_TYPE_POST
	query.AccountId = accountId
	cm := models.NewChannelMessage()
	messages, err := cm.FetchMessagesByChannelId(c.Id, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	buildMessageQuery.Limit = 3
	return response.HandleResultAndError(
		cm.BuildMessages(buildMessageQuery, messages),
	)
}

func FetchPostCount(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	accountId, err := request.GetId(u)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// Get Group Channel
	selector := map[string]interface{}{
		"group_name":    query.GroupName,
		"type_constant": models.Channel_TYPE_GROUP,
	}

	// first check channel existence
	c := models.NewChannel()
	if err := c.One(bongo.NewQS(selector)); err != nil {
		return response.NewBadRequest(err)
	}

	// check if user can open the channel
	ok, err := c.CanOpen(accountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !ok {
		return response.NewAccessDenied(nil)
	}

	// fetch user post count in koding channel
	q := request.NewQuery()
	q.AccountId = accountId
	q.Type = models.ChannelMessage_TYPE_POST
	q.GroupChannelId = c.Id
	cm := models.NewChannelMessage()

	count, err := cm.FetchTotalMessageCount(q)
	if err != nil {
		return response.NewBadRequest(err)
	}

	res := new(models.CountResponse)
	res.TotalCount = count

	return response.NewOK(res)
}

func Follow(u *url.URL, h http.Header, req *models.Account, context *models.Context) (int, http.Header, interface{}, error) {
	targetId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	return response.HandleResultAndError(
		req.Follow(targetId),
	)
}

func Register(u *url.URL, h http.Header, req *models.Account) (int, http.Header, interface{}, error) {

	if err := req.FetchOrCreate(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(req)
}

func Update(u *url.URL, h http.Header, req *models.Account, context *models.Context) (int, http.Header, interface{}, error) {
	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	if accountId != context.Client.Account.Id {
		return response.NewAccessDenied(models.ErrAccessDenied)
	}

	if accountId == 0 {
		return response.NewBadRequest(models.ErrAccountIdIsNotSet)
	}

	acc := models.NewAccount()
	if err := acc.ById(accountId); err != nil {
		return response.NewBadRequest(err)
	}

	acc.Nick = req.Nick

	if err := models.ValidateAccount(acc); err != nil {
		if err != models.ErrGuestsAreNotAllowed {
			return response.NewBadRequest(err)
		}
	}

	acc.Settings = req.Settings

	if err := acc.Update(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(acc)
}

func Unfollow(u *url.URL, h http.Header, req *models.Account, context *models.Context) (int, http.Header, interface{}, error) {
	targetId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	return response.HandleResultAndError(req.Unfollow(targetId))
}

func CheckOwnership(u *url.URL, h http.Header, context *models.Context) (int, http.Header, interface{}, error) {
	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	ownershipResponse := func(err error) (int, http.Header, interface{}, error) {
		var success bool
		switch err {
		case bongo.RecordNotFound:
			success = false
		case nil:
			success = true
		default:
			return response.NewBadRequest(err)
		}
		return response.NewOK(map[string]bool{"success": success})
	}

	switch query.Type {
	case "channel":
		channel := models.NewChannel()
		err = channel.One(&bongo.Query{
			Selector: map[string]interface{}{
				"id":         query.ObjectId,
				"creator_id": accountId,
			},
		})
	case "channel-message":
		channelMessage := models.NewChannelMessage()
		err = channelMessage.One(&bongo.Query{
			Selector: map[string]interface{}{
				"id":         query.ObjectId,
				"account_id": accountId,
			},
		})
	}
	return ownershipResponse(err)
}

func ListGroupChannels(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	cp := models.NewChannelParticipant()
	cids, err := cp.FetchAllParticipatedChannelIdsInGroup(c.Client.Account.Id, c.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	channels, err := models.NewChannel().FetchByIds(cids)
	if err != nil {
		return response.NewBadRequest(err)
	}

	cc := models.NewChannelContainers()
	cc.PopulateWith(channels, c.Client.Account.Id)

	return response.HandleResultAndError(cc, cc.Err())
}
<commit_msg>socialapi: remove context from Account Update func<commit_after>package account

import (
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/request"
	"socialapi/workers/common/response"
	"strconv"

	"github.com/koding/bongo"
)

// lists followed channels of an account
func ListChannels(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {

	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	query := request.GetQuery(u)
	query = c.OverrideQuery(query)
	if query.AccountId == 0 {
		query.AccountId = accountId
	}

	if query.Type == "" {
		query.Type = models.Channel_TYPE_TOPIC
	}

	a := &models.Account{Id: accountId}
	channels, err := a.FetchChannels(query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	cc := models.NewChannelContainers()
	cc.PopulateWith(channels, query.AccountId).AddUnreadCount(query.AccountId)

	return response.HandleResultAndError(cc, cc.Err())
}

func GetAccountFromSession(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	if c.Client == nil || c.Client.Account == nil {
		return response.NewNotFound()
	}

	res := map[string]interface{}{
		"id":    strconv.FormatInt(c.Client.Account.Id, 10),
		"nick":  c.Client.Account.Nick,
		"token": c.Client.Account.Token,
	}
	return response.NewOK(res)
}

func ParticipatedChannelCount(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	query := request.GetQuery(u)
	query = c.OverrideQuery(query)

	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if query.Type == "" {
		query.Type = models.Channel_TYPE_TOPIC
	}
	cp := models.NewChannelParticipant()
	a := &models.Account{Id: accountId}

	return response.HandleResultAndError(cp.ParticipatedChannelCount(a, query))
}

func ListPosts(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	buildMessageQuery := query.Clone()

	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	// Get Group Channel
	selector := map[string]interface{}{
		"group_name":    query.GroupName,
		"type_constant": models.Channel_TYPE_GROUP,
	}

	c := models.NewChannel()
	if err := c.One(bongo.NewQS(selector)); err != nil {
		return response.NewBadRequest(err)
	}
	// fetch only channel messages
	query.Type = models.ChannelMessage_TYPE_POST
	query.AccountId = accountId
	cm := models.NewChannelMessage()
	messages, err := cm.FetchMessagesByChannelId(c.Id, query)
	if err != nil {
		return response.NewBadRequest(err)
	}

	buildMessageQuery.Limit = 3
	return response.HandleResultAndError(
		cm.BuildMessages(buildMessageQuery, messages),
	)
}

func FetchPostCount(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	accountId, err := request.GetId(u)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// Get Group Channel
	selector := map[string]interface{}{
		"group_name":    query.GroupName,
		"type_constant": models.Channel_TYPE_GROUP,
	}

	// first check channel existence
	c := models.NewChannel()
	if err := c.One(bongo.NewQS(selector)); err != nil {
		return response.NewBadRequest(err)
	}

	// check if user can open the channel
	ok, err := c.CanOpen(accountId)
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !ok {
		return response.NewAccessDenied(nil)
	}

	// fetch user post count in koding channel
	q := request.NewQuery()
	q.AccountId = accountId
	q.Type = models.ChannelMessage_TYPE_POST
	q.GroupChannelId = c.Id
	cm := models.NewChannelMessage()

	count, err := cm.FetchTotalMessageCount(q)
	if err != nil {
		return response.NewBadRequest(err)
	}

	res := new(models.CountResponse)
	res.TotalCount = count

	return response.NewOK(res)
}

func Follow(u *url.URL, h http.Header, req *models.Account, context *models.Context) (int, http.Header, interface{}, error) {
	targetId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	return response.HandleResultAndError(
		req.Follow(targetId),
	)
}

func Register(u *url.URL, h http.Header, req *models.Account) (int, http.Header, interface{}, error) {

	if err := req.FetchOrCreate(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(req)
}

// Update modifies account data to the lates version by default all requests
// coming to this handler are trusted & validity of the parameters are not
// checked.
//
func Update(u *url.URL, h http.Header, req *models.Account) (int, http.Header, interface{}, error) {
	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if accountId == 0 {
		return response.NewBadRequest(models.ErrAccountIdIsNotSet)
	}

	acc := models.NewAccount()
	if err := acc.ById(accountId); err != nil {
		return response.NewBadRequest(err)
	}

	acc.Nick = req.Nick

	if err := models.ValidateAccount(acc); err != nil {
		if err != models.ErrGuestsAreNotAllowed {
			return response.NewBadRequest(err)
		}
	}

	acc.Settings = req.Settings

	if err := acc.Update(); err != nil {
		return response.NewBadRequest(err)
	}

	return response.NewOK(acc)
}

func Unfollow(u *url.URL, h http.Header, req *models.Account, context *models.Context) (int, http.Header, interface{}, error) {
	targetId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	return response.HandleResultAndError(req.Unfollow(targetId))
}

func CheckOwnership(u *url.URL, h http.Header, context *models.Context) (int, http.Header, interface{}, error) {
	accountId, err := request.GetURIInt64(u, "id")
	if err != nil {
		return response.NewBadRequest(err)
	}

	query := request.GetQuery(u)
	query = context.OverrideQuery(query)

	ownershipResponse := func(err error) (int, http.Header, interface{}, error) {
		var success bool
		switch err {
		case bongo.RecordNotFound:
			success = false
		case nil:
			success = true
		default:
			return response.NewBadRequest(err)
		}
		return response.NewOK(map[string]bool{"success": success})
	}

	switch query.Type {
	case "channel":
		channel := models.NewChannel()
		err = channel.One(&bongo.Query{
			Selector: map[string]interface{}{
				"id":         query.ObjectId,
				"creator_id": accountId,
			},
		})
	case "channel-message":
		channelMessage := models.NewChannelMessage()
		err = channelMessage.One(&bongo.Query{
			Selector: map[string]interface{}{
				"id":         query.ObjectId,
				"account_id": accountId,
			},
		})
	}
	return ownershipResponse(err)
}

func ListGroupChannels(u *url.URL, h http.Header, _ interface{}, c *models.Context) (int, http.Header, interface{}, error) {
	if !c.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	cp := models.NewChannelParticipant()
	cids, err := cp.FetchAllParticipatedChannelIdsInGroup(c.Client.Account.Id, c.GroupName)
	if err != nil {
		return response.NewBadRequest(err)
	}

	channels, err := models.NewChannel().FetchByIds(cids)
	if err != nil {
		return response.NewBadRequest(err)
	}

	cc := models.NewChannelContainers()
	cc.PopulateWith(channels, c.Client.Account.Id)

	return response.HandleResultAndError(cc, cc.Err())
}
<|endoftext|>


<commit_before>package payment

import (
	"net/http"
	"net/url"

	"socialapi/workers/common/response"
	"socialapi/workers/payment"
)

func Subscribe(u *url.URL, h http.Header, req *payment.SubscribeRequest) (int, http.Header, interface{}, error) {
	return response.HandleResultAndError(
		req.Do(),
	)
}

func SubscriptionRequest(u *url.URL, h http.Header, req *payment.SubscriptionRequest) (int, http.Header, interface{}, error) {
	req.AccountId = u.Query().Get("accountId")

	return response.HandleResultAndError(
		req.Do(),
	)
}

func StripeWebhook(u *url.URL, h http.Header, req *payment.StripeWebhook) (int, http.Header, interface{}, error) {
	return response.HandleResultAndError(
		req.Do(),
	)
}
<commit_msg>payment: minor fix<commit_after>package payment

import (
	"net/http"
	"net/url"

	"socialapi/workers/common/response"
	"socialapi/workers/payment"
)

func Subscribe(u *url.URL, h http.Header, req *payment.SubscribeRequest) (int, http.Header, interface{}, error) {
	return response.HandleResultAndError(
		req.Do(),
	)
}

func SubscriptionRequest(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	subscriptionRequest := &payment.SubscriptionRequest{
		AccountId: u.Query().Get("accountId"),
	}

	return response.HandleResultAndError(
		subscriptionRequest.Do(),
	)
}

func StripeWebhook(u *url.URL, h http.Header, req *payment.StripeWebhook) (int, http.Header, interface{}, error) {
	return response.HandleResultAndError(
		req.Do(),
	)
}
<|endoftext|>


<commit_before>// Copyright 2013 com authors
//
// 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 com

import (
	"encoding/base64"
	"math"
	"net/url"
	"path"
	"regexp"
	"strings"
)

// URLEncode url encode string, is + not %20
func URLEncode(str string) string {
	return url.QueryEscape(str)
}

// URLDecode url decode string
func URLDecode(str string) (string, error) {
	return url.QueryUnescape(str)
}

// Base64Encode base64 encode
func Base64Encode(str string) string {
	return base64.StdEncoding.EncodeToString([]byte(str))
}

// Base64Decode base64 decode
func Base64Decode(str string) (string, error) {
	s, e := base64.StdEncoding.DecodeString(str)
	return string(s), e
}

// SafeBase64Encode base64 encode
func SafeBase64Encode(str string) string {
	str = Base64Encode(str)
	str = strings.TrimRight(str, `=`)
	str = strings.Replace(str, `/`, `_`, -1)
	str = strings.Replace(str, `+`, `-`, -1)
	return str
}

// SafeBase64Decode base64 decode
func SafeBase64Decode(str string) (string, error) {
	str = strings.Replace(str, `_`, `/`, -1)
	str = strings.Replace(str, `-`, `+`, -1)
	var missing = (4 - len(str)%4) % 4
	str += strings.Repeat(`=`, missing)
	return Base64Decode(str)
}

// TotalPages 总页数
func TotalPages(totalRows uint, limit uint) uint {
	return uint(math.Ceil(float64(totalRows) / float64(limit)))
}

// Offset 根据页码计算偏移值
func Offset(page uint, limit uint) uint {
	if page == 0 {
		page = 1
	}
	return (page - 1) * limit
}

// AbsURL 获取页面内相对网址的绝对路径
func AbsURL(pageURL string, relURL string) string {
	if strings.Contains(relURL, `://`) {
		return relURL
	}
	urlInfo, err := url.Parse(pageURL)
	if err != nil {
		return ``
	}
	siteURL := urlInfo.Scheme + `://` + urlInfo.Host
	if strings.HasPrefix(relURL, `/`) {
		return siteURL + relURL
	}
	for strings.HasPrefix(relURL, `./`) {
		relURL = strings.TrimPrefix(relURL, `./`)
	}
	urlPath := path.Dir(urlInfo.Path)
	for strings.HasPrefix(relURL, `../`) {
		urlPath = path.Dir(urlPath)
		relURL = strings.TrimPrefix(relURL, `../`)
	}
	return siteURL + path.Join(urlPath, relURL)
}

var localIPRegexp = regexp.MustCompile(`^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$`)

// IsLocalhost 是否是本地主机
func IsLocalhost(host string) bool {
	switch host {
	case `localhost`:
		return true
	case `[::1]`:
		return true
	default:
		return localIPRegexp.MatchString(host)
	}
}
<commit_msg>update<commit_after>// Copyright 2013 com authors
//
// 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 com

import (
	"encoding/base64"
	"math"
	"net/url"
	"path"
	"regexp"
	"strings"
)

// URLEncode url encode string, is + not %20
func URLEncode(str string) string {
	return url.QueryEscape(str)
}

// URLDecode url decode string
func URLDecode(str string) (string, error) {
	return url.QueryUnescape(str)
}

// Base64Encode base64 encode
func Base64Encode(str string) string {
	return base64.StdEncoding.EncodeToString([]byte(str))
}

// Base64Decode base64 decode
func Base64Decode(str string) (string, error) {
	s, e := base64.StdEncoding.DecodeString(str)
	return string(s), e
}

// URLSafeBase64 base64字符串编码为URL友好的字符串
func URLSafeBase64(str string, encode bool) string {
	if encode { // 编码后处理
		str = strings.TrimRight(str, `=`)
		str = strings.Replace(str, `/`, `_`, -1)
		str = strings.Replace(str, `+`, `-`, -1)
		return str
	}
	// 解码前处理
	str = strings.Replace(str, `_`, `/`, -1)
	str = strings.Replace(str, `-`, `+`, -1)
	var missing = (4 - len(str)%4) % 4
	str += strings.Repeat(`=`, missing)
	return str
}

// SafeBase64Encode base64 encode
func SafeBase64Encode(str string) string {
	str = Base64Encode(str)
	return URLSafeBase64(str, true)
}

// SafeBase64Decode base64 decode
func SafeBase64Decode(str string) (string, error) {
	str = URLSafeBase64(str, false)
	return Base64Decode(str)
}

// TotalPages 总页数
func TotalPages(totalRows uint, limit uint) uint {
	return uint(math.Ceil(float64(totalRows) / float64(limit)))
}

// Offset 根据页码计算偏移值
func Offset(page uint, limit uint) uint {
	if page == 0 {
		page = 1
	}
	return (page - 1) * limit
}

// AbsURL 获取页面内相对网址的绝对路径
func AbsURL(pageURL string, relURL string) string {
	if strings.Contains(relURL, `://`) {
		return relURL
	}
	urlInfo, err := url.Parse(pageURL)
	if err != nil {
		return ``
	}
	siteURL := urlInfo.Scheme + `://` + urlInfo.Host
	if strings.HasPrefix(relURL, `/`) {
		return siteURL + relURL
	}
	for strings.HasPrefix(relURL, `./`) {
		relURL = strings.TrimPrefix(relURL, `./`)
	}
	urlPath := path.Dir(urlInfo.Path)
	for strings.HasPrefix(relURL, `../`) {
		urlPath = path.Dir(urlPath)
		relURL = strings.TrimPrefix(relURL, `../`)
	}
	return siteURL + path.Join(urlPath, relURL)
}

var localIPRegexp = regexp.MustCompile(`^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$`)

// IsLocalhost 是否是本地主机
func IsLocalhost(host string) bool {
	switch host {
	case `localhost`:
		return true
	case `[::1]`:
		return true
	default:
		return localIPRegexp.MatchString(host)
	}
}
<|endoftext|>


<commit_before>package util

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"regexp"
	"strings"
)

// URL を分解する。
// <scheme>://<host><remain>
func SplitUrl(url string) (scheme, host, remain string, err error) {
	idx := strings.Index(url, "://")
	if idx < 0 {
		return "", "", "", erro.New("invalid url " + url + ".")
	}

	scheme = url[:idx]
	host = url[idx+len("://"):]

	idx = strings.Index(host, "/")
	if idx >= 0 {
		remain = host[idx:]
		host = host[:idx]
	}

	return scheme, host, remain, nil
}

var slashes *regexp.Regexp

func init() {
	slashes = regexp.MustCompile("/+")
}

func MergeSlash(str string) string {
	return slashes.ReplaceAllString(str, "/")
}
<commit_msg>テスト UI を表面だけリバースプロキシに対応させた<commit_after>package util

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"net/http"
	"regexp"
	"strings"
)

// URL を分解する。
// <scheme>://<host><remain>
func SplitUrl(url string) (scheme, host, remain string, err error) {
	idx := strings.Index(url, "://")
	if idx < 0 {
		return "", "", "", erro.New("invalid url " + url + ".")
	}

	scheme = url[:idx]
	host = url[idx+len("://"):]

	idx = strings.Index(host, "/")
	if idx >= 0 {
		remain = host[idx:]
		host = host[:idx]
	}

	return scheme, host, remain, nil
}

var slashes *regexp.Regexp

func init() {
	slashes = regexp.MustCompile("/+")
}

func MergeSlash(str string) string {
	return slashes.ReplaceAllString(str, "/")
}

func UrlPrefix(r *http.Request) string {
	var prefix string
	if s := r.Header.Get("X-Forwarded-Proto"); s != "" {
		prefix = s
	} else if s := r.Header.Get("X-Forwarded-Ssl"); s == "on" {
		prefix = "https"
	} else {
		prefix = "http"
	}

	prefix += "://"

	if h := r.Header.Get("X-Forwarded-Host"); h != "" {
		prefix += h
	} else {
		prefix += r.Host
	}

	return prefix
}
<|endoftext|>


<commit_before>package air

import "net/url"

// URL represents the HTTP URL of the current HTTP request.
//
// It's embedded with `url.URL`.
type URL struct {
	*url.URL

	queryValues url.Values
}

// newURL returns a pointer of a new instance of `URL`.
func newURL() *URL {
	return &URL{}
}

// QueryValue returns the query value for the provided key.
func (url *URL) QueryValue(key string) string {
	if url.queryValues == nil {
		url.queryValues = url.Query()
	}
	return url.queryValues.Get(key)
}

// QueryValues returns the query values.
func (url *URL) QueryValues() url.Values {
	if url.queryValues == nil {
		url.queryValues = url.Query()
	}
	return url.queryValues
}

// reset resets all fields in the url.
func (url *URL) reset() {
	url.URL = nil
	url.queryValues = nil
}
<commit_msg>chore: simplify code in url.go<commit_after>package air

import "net/url"

// URL represents the HTTP URL of the current HTTP request.
//
// It's embedded with `url.URL`.
type URL struct {
	*url.URL

	queryValues url.Values
}

// newURL returns a pointer of a new instance of `URL`.
func newURL() *URL {
	return &URL{}
}

// QueryValue returns the query value for the provided key.
func (url *URL) QueryValue(key string) string {
	return url.QueryValues().Get(key)
}

// QueryValues returns the query values.
func (url *URL) QueryValues() url.Values {
	if url.queryValues == nil {
		url.queryValues = url.Query()
	}
	return url.queryValues
}

// reset resets all fields in the url.
func (url *URL) reset() {
	url.URL = nil
	url.queryValues = nil
}
<|endoftext|>


<commit_before>// This file was auto-generated using createmock. See the following page for
// more information:
//
//     https://github.com/jacobsa/oglemock
//

package mock_backup

import (
	fmt "fmt"
	backup "github.com/jacobsa/comeback/backup"
	blob "github.com/jacobsa/comeback/blob"
	oglemock "github.com/jacobsa/oglemock"
	io "io"
	runtime "runtime"
	unsafe "unsafe"
)

type MockFileSaver interface {
	backup.FileSaver
	oglemock.MockObject
}

type mockFileSaver struct {
	controller  oglemock.Controller
	description string
}

func NewMockFileSaver(
	c oglemock.Controller,
	desc string) MockFileSaver {
	return &mockFileSaver{
		controller:  c,
		description: desc,
	}
}

func (m *mockFileSaver) Oglemock_Id() uintptr {
	return uintptr(unsafe.Pointer(m))
}

func (m *mockFileSaver) Oglemock_Description() string {
	return m.description
}

func (m *mockFileSaver) Save(p0 io.Reader) (o0 []blob.Score, o1 error) {
	// Get a file name and line number for the caller.
	_, file, line, _ := runtime.Caller(1)

	// Hand the call off to the controller, which does most of the work.
	retVals := m.controller.HandleMethodCall(
		m,
		"Save",
		file,
		line,
		[]interface{}{p0})

	if len(retVals) != 2 {
		panic(fmt.Sprintf("mockFileSaver.Save: invalid return values: %v", retVals))
	}

	// o0 []blob.Score
	if retVals[0] != nil {
		o0 = retVals[0].([]blob.Score)
	}

	// o1 error
	if retVals[1] != nil {
		o1 = retVals[1].(error)
	}

	return
}

type MockDirectorySaver interface {
	backup.DirectorySaver
	oglemock.MockObject
}

type mockDirectorySaver struct {
	controller  oglemock.Controller
	description string
}

func NewMockDirectorySaver(
	c oglemock.Controller,
	desc string) MockDirectorySaver {
	return &mockDirectorySaver{
		controller:  c,
		description: desc,
	}
}

func (m *mockDirectorySaver) Oglemock_Id() uintptr {
	return uintptr(unsafe.Pointer(m))
}

func (m *mockDirectorySaver) Oglemock_Description() string {
	return m.description
}

func (m *mockDirectorySaver) Save(p0 string) (o0 blob.Score, o1 error) {
	// Get a file name and line number for the caller.
	_, file, line, _ := runtime.Caller(1)

	// Hand the call off to the controller, which does most of the work.
	retVals := m.controller.HandleMethodCall(
		m,
		"Save",
		file,
		line,
		[]interface{}{p0})

	if len(retVals) != 2 {
		panic(fmt.Sprintf("mockDirectorySaver.Save: invalid return values: %v", retVals))
	}

	// o0 blob.Score
	if retVals[0] != nil {
		o0 = retVals[0].(blob.Score)
	}

	// o1 error
	if retVals[1] != nil {
		o1 = retVals[1].(error)
	}

	return
}
<commit_msg>Added a mock link resolver.<commit_after>// This file was auto-generated using createmock. See the following page for
// more information:
//
//     https://github.com/jacobsa/oglemock
//

package mock_backup

import (
	backup "github.com/jacobsa/comeback/backup"
	blob "github.com/jacobsa/comeback/blob"
	fmt "fmt"
	io "io"
	oglemock "github.com/jacobsa/oglemock"
	runtime "runtime"
	unsafe "unsafe"
)

type MockFileSaver interface {
	backup.FileSaver
	oglemock.MockObject
}

type mockFileSaver struct {
	controller	oglemock.Controller
	description	string
}

func NewMockFileSaver(
	c oglemock.Controller,
	desc string) MockFileSaver {
	return &mockFileSaver{
		controller:	c,
		description:	desc,
	}
}

func (m *mockFileSaver) Oglemock_Id() uintptr {
	return uintptr(unsafe.Pointer(m))
}

func (m *mockFileSaver) Oglemock_Description() string {
	return m.description
}

func (m *mockFileSaver) Save(p0 io.Reader) (o0 []blob.Score, o1 error) {
	// Get a file name and line number for the caller.
	_, file, line, _ := runtime.Caller(1)

	// Hand the call off to the controller, which does most of the work.
	retVals := m.controller.HandleMethodCall(
		m,
		"Save",
		file,
		line,
		[]interface{}{p0})

	if len(retVals) != 2 {
		panic(fmt.Sprintf("mockFileSaver.Save: invalid return values: %v", retVals))
	}

	// o0 []blob.Score
	if retVals[0] != nil {
		o0 = retVals[0].([]blob.Score)
	}

	// o1 error
	if retVals[1] != nil {
		o1 = retVals[1].(error)
	}

	return
}

type MockDirectorySaver interface {
	backup.DirectorySaver
	oglemock.MockObject
}

type mockDirectorySaver struct {
	controller	oglemock.Controller
	description	string
}

func NewMockDirectorySaver(
	c oglemock.Controller,
	desc string) MockDirectorySaver {
	return &mockDirectorySaver{
		controller:	c,
		description:	desc,
	}
}

func (m *mockDirectorySaver) Oglemock_Id() uintptr {
	return uintptr(unsafe.Pointer(m))
}

func (m *mockDirectorySaver) Oglemock_Description() string {
	return m.description
}

func (m *mockDirectorySaver) Save(p0 string) (o0 blob.Score, o1 error) {
	// Get a file name and line number for the caller.
	_, file, line, _ := runtime.Caller(1)

	// Hand the call off to the controller, which does most of the work.
	retVals := m.controller.HandleMethodCall(
		m,
		"Save",
		file,
		line,
		[]interface{}{p0})

	if len(retVals) != 2 {
		panic(fmt.Sprintf("mockDirectorySaver.Save: invalid return values: %v", retVals))
	}

	// o0 blob.Score
	if retVals[0] != nil {
		o0 = retVals[0].(blob.Score)
	}

	// o1 error
	if retVals[1] != nil {
		o1 = retVals[1].(error)
	}

	return
}

type MockLinkResolver interface {
	backup.LinkResolver
	oglemock.MockObject
}

type mockLinkResolver struct {
	controller	oglemock.Controller
	description	string
}

func NewMockLinkResolver(
	c oglemock.Controller,
	desc string) MockLinkResolver {
	return &mockLinkResolver{
		controller:	c,
		description:	desc,
	}
}

func (m *mockLinkResolver) Oglemock_Id() uintptr {
	return uintptr(unsafe.Pointer(m))
}

func (m *mockLinkResolver) Oglemock_Description() string {
	return m.description
}

func (m *mockLinkResolver) Register(p0 int32, p1 uint64, p2 string) (o0 *string) {
	// Get a file name and line number for the caller.
	_, file, line, _ := runtime.Caller(1)

	// Hand the call off to the controller, which does most of the work.
	retVals := m.controller.HandleMethodCall(
		m,
		"Register",
		file,
		line,
		[]interface{}{p0, p1, p2})

	if len(retVals) != 1 {
		panic(fmt.Sprintf("mockLinkResolver.Register: invalid return values: %v", retVals))
	}

	// o0 *string
	if retVals[0] != nil {
		o0 = retVals[0].(*string)
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
	mp "github.com/mackerelio/go-mackerel-plugin"
)

// metric value structure
var graphdef map[string](mp.Graphs) = map[string](mp.Graphs){
	"apache2.workers": mp.Graphs{
		Label: "Apache Workers",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "busy_workers", Label: "Busy Workers", Diff: false, Stacked: true},
			mp.Metrics{Name: "idle_workers", Label: "Idle Workers", Diff: false, Stacked: true},
		},
	},
	"apache2.bytes": mp.Graphs{
		Label: "Apache Bytes",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "bytes_sent", Label: "Bytes Sent", Diff: false},
		},
	},
	"apache2.cpu": mp.Graphs{
		Label: "Apache CPU Load",
		Unit:  "float",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "cpu_load", Label: "CPU Load", Diff: false},
		},
	},
	"apache2.req": mp.Graphs{
		Label: "Apache Requests",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "requests", Label: "Requests", Diff: false},
		},
	},
	"apache2.scoreboard": mp.Graphs{
		Label: "Apache Scoreboard",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "score-_", Label: "Waiting for connection", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-S", Label: "Starting up", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-R", Label: "Reading request", Diff: false, Stacked: true},
			mp.Metrics{Name: "scpre-W", Label: "Sending reply", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-K", Label: "Keepalive", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-D", Label: "DNS lookup", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-C", Label: "Closing connection", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-L", Label: "Logging", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-G", Label: "Gracefully finishing", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-I", Label: "Idle cleanup", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-.", Label: "Open slot", Diff: false, Stacked: true},
		},
	},
}

// for fetching metrics
type Apache2Plugin struct {
	Host     string
	Port     uint16
	Path     string
	Tempfile string
}

// Graph definition
func (c Apache2Plugin) GraphDefinition() map[string](mp.Graphs) {
	return graphdef
}

// main function
func doMain(c *cli.Context) {

	var apache2 Apache2Plugin

	apache2.Host = c.String("http_host")
	apache2.Port = uint16(c.Int("http_port"))
	apache2.Path = c.String("status_page")
	apache2.Tempfile = c.String("tempfile")

	helper := mp.NewMackerelPlugin(apache2)

	if os.Getenv("MACKEREL_AGENT_PLUGIN_META") != "" {
		helper.OutputDefinitions()
	} else {
		helper.OutputValues()
	}
}

// fetch metrics
func (c Apache2Plugin) FetchMetrics() (map[string]float64, error) {
	data, err := getApache2Metrics(c.Host, c.Port, c.Path)
	if err != nil {
		return nil, err
	}

	stat := make(map[string]float64)
	err_stat := parseApache2Status(data, &stat)
	if err_stat != nil {
		return nil, err_stat
	}
	err_score := parseApache2Scoreboard(data, &stat)
	if err_score != nil {
		return nil, err_score
	}

	return stat, nil
}

// parsing scoreboard from server-status?auto
func parseApache2Scoreboard(str string, p *map[string]float64) error {
	for _, line := range strings.Split(str, "\n") {
		matched, err := regexp.MatchString("Scoreboard(.*)", line)
		if err != nil {
			return err
		}
		if !matched {
			continue
		}
		record := strings.Split(line, ":")
		for _, sb := range strings.Split(strings.Trim(record[1], " "), "") {
			name := fmt.Sprintf("score-%s", sb)
			c, assert := (*p)[name]
			if !assert {
				c = 0
			}
			(*p)[name] = c + 1
		}
		return nil
	}

	return errors.New("Scoreboard data is not found.")
}

// parsing metrics from server-status?auto
func parseApache2Status(str string, p *map[string]float64) error {
	Params := map[string]string{
		"Total Accesses": "requests",
		"Total kBytes":   "bytes_sent",
		"CPULoad":        "cpu_load",
		"BusyWorkers":    "busy_workers",
		"IdleWorkers":    "idle_workers"}

	for _, line := range strings.Split(str, "\n") {
		record := strings.Split(line, ":")
		_, assert := Params[record[0]]
		if !assert {
			continue
		}
		var err_parse error
		(*p)[Params[record[0]]], err_parse = strconv.ParseFloat(strings.Trim(record[1], " "), 64)
		if err_parse != nil {
			return err_parse
		}
	}

	if len(*p) == 0 {
		return errors.New("Status data not found.")
	}

	return nil
}

// Getting apache2 status from server-status module data.
func getApache2Metrics(host string, port uint16, path string) (string, error) {
	uri := "http://" + host + ":" + strconv.FormatUint(uint64(port), 10) + path
	resp, err := http.Get(uri)
	if err != nil {
		return "", err
	}
	if resp.StatusCode != http.StatusOK {
		return "", errors.New(fmt.Sprintf("HTTP status error: %d", resp.StatusCode))
	}
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		return "", err
	}
	return string(body[:]), nil
}

// main
func main() {
	app := cli.NewApp()
	app.Name = "apache2_metrics"
	app.Version = Version
	app.Usage = "Get metrics from apache2."
	app.Author = "Yuichiro Saito"
	app.Email = "saito@heartbeats.jp"
	app.Flags = Flags
	app.Action = doMain

	app.Run(os.Args)
}
<commit_msg>Change metric method to bytes, requests<commit_after>package main

import (
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strconv"
	"strings"

	"github.com/codegangsta/cli"
	mp "github.com/mackerelio/go-mackerel-plugin"
)

// metric value structure
var graphdef map[string](mp.Graphs) = map[string](mp.Graphs){
	"apache2.workers": mp.Graphs{
		Label: "Apache Workers",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "busy_workers", Label: "Busy Workers", Diff: false, Stacked: true},
			mp.Metrics{Name: "idle_workers", Label: "Idle Workers", Diff: false, Stacked: true},
		},
	},
	"apache2.bytes": mp.Graphs{
		Label: "Apache Bytes",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "bytes_sent", Label: "Bytes Sent", Diff: true},
		},
	},
	"apache2.cpu": mp.Graphs{
		Label: "Apache CPU Load",
		Unit:  "float",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "cpu_load", Label: "CPU Load", Diff: false},
		},
	},
	"apache2.req": mp.Graphs{
		Label: "Apache Requests",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "requests", Label: "Requests", Diff: true},
		},
	},
	"apache2.scoreboard": mp.Graphs{
		Label: "Apache Scoreboard",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "score-_", Label: "Waiting for connection", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-S", Label: "Starting up", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-R", Label: "Reading request", Diff: false, Stacked: true},
			mp.Metrics{Name: "scpre-W", Label: "Sending reply", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-K", Label: "Keepalive", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-D", Label: "DNS lookup", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-C", Label: "Closing connection", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-L", Label: "Logging", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-G", Label: "Gracefully finishing", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-I", Label: "Idle cleanup", Diff: false, Stacked: true},
			mp.Metrics{Name: "score-.", Label: "Open slot", Diff: false, Stacked: true},
		},
	},
}

// for fetching metrics
type Apache2Plugin struct {
	Host     string
	Port     uint16
	Path     string
	Tempfile string
}

// Graph definition
func (c Apache2Plugin) GraphDefinition() map[string](mp.Graphs) {
	return graphdef
}

// main function
func doMain(c *cli.Context) {

	var apache2 Apache2Plugin

	apache2.Host = c.String("http_host")
	apache2.Port = uint16(c.Int("http_port"))
	apache2.Path = c.String("status_page")

	helper := mp.NewMackerelPlugin(apache2)
	helper.Tempfile = c.String("tempfile")

	if os.Getenv("MACKEREL_AGENT_PLUGIN_META") != "" {
		helper.OutputDefinitions()
	} else {
		helper.OutputValues()
	}
}

// fetch metrics
func (c Apache2Plugin) FetchMetrics() (map[string]float64, error) {
	data, err := getApache2Metrics(c.Host, c.Port, c.Path)
	if err != nil {
		return nil, err
	}

	stat := make(map[string]float64)
	err_stat := parseApache2Status(data, &stat)
	if err_stat != nil {
		return nil, err_stat
	}
	err_score := parseApache2Scoreboard(data, &stat)
	if err_score != nil {
		return nil, err_score
	}

	return stat, nil
}

// parsing scoreboard from server-status?auto
func parseApache2Scoreboard(str string, p *map[string]float64) error {
	for _, line := range strings.Split(str, "\n") {
		matched, err := regexp.MatchString("Scoreboard(.*)", line)
		if err != nil {
			return err
		}
		if !matched {
			continue
		}
		record := strings.Split(line, ":")
		for _, sb := range strings.Split(strings.Trim(record[1], " "), "") {
			name := fmt.Sprintf("score-%s", sb)
			c, assert := (*p)[name]
			if !assert {
				c = 0
			}
			(*p)[name] = c + 1
		}
		return nil
	}

	return errors.New("Scoreboard data is not found.")
}

// parsing metrics from server-status?auto
func parseApache2Status(str string, p *map[string]float64) error {
	Params := map[string]string{
		"Total Accesses": "requests",
		"Total kBytes":   "bytes_sent",
		"CPULoad":        "cpu_load",
		"BusyWorkers":    "busy_workers",
		"IdleWorkers":    "idle_workers"}

	for _, line := range strings.Split(str, "\n") {
		record := strings.Split(line, ":")
		_, assert := Params[record[0]]
		if !assert {
			continue
		}
		var err_parse error
		(*p)[Params[record[0]]], err_parse = strconv.ParseFloat(strings.Trim(record[1], " "), 64)
		if err_parse != nil {
			return err_parse
		}
	}

	if len(*p) == 0 {
		return errors.New("Status data not found.")
	}

	return nil
}

// Getting apache2 status from server-status module data.
func getApache2Metrics(host string, port uint16, path string) (string, error) {
	uri := "http://" + host + ":" + strconv.FormatUint(uint64(port), 10) + path
	resp, err := http.Get(uri)
	if err != nil {
		return "", err
	}
	if resp.StatusCode != http.StatusOK {
		return "", errors.New(fmt.Sprintf("HTTP status error: %d", resp.StatusCode))
	}
	body, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		return "", err
	}
	return string(body[:]), nil
}

// main
func main() {
	app := cli.NewApp()
	app.Name = "apache2_metrics"
	app.Version = Version
	app.Usage = "Get metrics from apache2."
	app.Author = "Yuichiro Saito"
	app.Email = "saito@heartbeats.jp"
	app.Flags = Flags
	app.Action = doMain

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


<commit_before><commit_msg>支持解密 分享数据 得到 openGId (#406)<commit_after><|endoftext|>


<commit_before>package participant

import (
	"fmt"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/api/modules/helpers"

	"github.com/jinzhu/gorm"
)

func List(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	channelId, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		fmt.Println(err)
		return helpers.NewBadRequestResponse(err)
	}

	req := models.NewChannelParticipant()
	req.ChannelId = channelId
	participants, err := req.List()
	if err != nil {
		if err == gorm.RecordNotFound {
			return helpers.NewNotFoundResponse()
		}
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(participants)
}

func Add(u *url.URL, h http.Header, req *models.ChannelParticipant) (int, http.Header, interface{}, error) {
	channelId, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	accountId, err := helpers.GetURIInt64(u, "accountId")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req.AccountId = accountId
	req.ChannelId = channelId
	req.StatusConstant = models.ChannelParticipant_STATUS_ACTIVE

	if err := req.Create(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func Delete(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	channelId, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	accountId, err := helpers.GetURIInt64(u, "accountId")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req := models.NewChannelParticipant()
	req.AccountId = accountId
	req.ChannelId = channelId

	if err := req.Delete(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	// yes it is deleted but not removed completely from our system
	return helpers.NewDeletedResponse()
}
<commit_msg>Social: add checking prerequisite controls for channel participant operations<commit_after>package participant

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/api/modules/helpers"

	"github.com/jinzhu/gorm"
)

func List(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	channelId, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		fmt.Println(err)
		return helpers.NewBadRequestResponse(err)
	}

	req := models.NewChannelParticipant()
	req.ChannelId = channelId
	participants, err := req.List()
	if err != nil {
		if err == gorm.RecordNotFound {
			return helpers.NewNotFoundResponse()
		}
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(participants)
}

func Add(u *url.URL, h http.Header, req *models.ChannelParticipant) (int, http.Header, interface{}, error) {
	channelId, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	accountId, err := helpers.GetURIInt64(u, "accountId")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	if err := checkChannelPrerequisites(channelId, accountId); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req.AccountId = accountId
	req.ChannelId = channelId
	req.StatusConstant = models.ChannelParticipant_STATUS_ACTIVE

	if err := req.Create(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func checkChannelPrerequisites(channelId, accountId int64) error {
	c := models.NewChannel()
	c.Id = channelId
	if err := c.Fetch(); err != nil {
		return err
	}
	if c.TypeConstant == models.Channel_TYPE_PINNED_ACTIVITY {
		return errors.New("You can not add a new participant into pinned activity channel")
	}
	return nil
}

func Delete(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	channelId, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	accountId, err := helpers.GetURIInt64(u, "accountId")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req := models.NewChannelParticipant()
	req.AccountId = accountId
	req.ChannelId = channelId

	if err := req.Delete(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	// yes it is deleted but not removed completely from our system
	return helpers.NewDeletedResponse()
}
<|endoftext|>


<commit_before>package vm

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

var kvss = [][][2]*Thunk{
	{{True, False}},
	{{Nil, NewNumber(42)}},
	{{False, NewNumber(42)}, {True, NewNumber(13)}},
	{
		{False, NewNumber(42)},
		{True, False},
		{NewNumber(2), NewString("Mr. Value")},
	},
	{
		{NewString("go"), NewList(NewList(), Nil, NewNumber(123))},
		{False, NewNumber(42)},
		{True, False},
		{NewNumber(2), NewString("Mr. Value")},
	},
}

func TestDictionarySet(t *testing.T) {
	for _, k := range []*Thunk{
		True, False, Nil, NewNumber(42), NewString("risp"),
	} {
		_, ok := App(Set, EmptyDictionary, k, Nil).Eval().(dictionaryType)
		assert.True(t, ok)
	}
}

func TestDictionaryGet(t *testing.T) {
	for _, kvs := range kvss {
		d := EmptyDictionary

		for i, kv := range kvs {
			t.Logf("Setting a %vth key...\n", i)
			d = App(Set, d, kv[0], kv[1])
		}

		assert.Equal(t, len(kvs), dictionarySize(d))

		for i, kv := range kvs {
			t.Logf("Getting a %vth value...\n", i)

			k, v := kv[0], kv[1]

			t.Log(k.Eval())

			if e, ok := App(Get, d, k).Eval().(errorType); ok {
				t.Log(e.message.Eval())
			}

			assert.True(t, testEqual(App(Get, d, k), v))
		}
	}
}

func TestDictionaryToList(t *testing.T) {
	for i, kvs := range kvss {
		t.Log("TestDictionaryToList START", i)
		d := EmptyDictionary

		for i, kv := range kvs {
			t.Logf("Setting a %vth key...\n", i)
			d = App(Set, d, kv[0], kv[1])
		}

		assert.Equal(t, len(kvs), dictionarySize(d))

		l := App(ToList, d)

		for i := 0; i < len(kvs); i, l = i+1, App(Rest, l) {
			kv := App(First, l)
			k := App(First, kv)
			lv := App(First, App(Rest, kv))
			dv := App(Get, d, k)

			t.Log("Key:", k.Eval())
			t.Log("LIST Value:", lv.Eval())
			t.Log("DICT Value:", dv.Eval())

			assert.True(t, testEqual(lv, dv))
		}

		assert.Equal(t, l.Eval().(listType), emptyList)
	}
}

func dictionarySize(d *Thunk) int {
	return int(d.Eval().(dictionaryType).hashMap.Size())
}
<commit_msg>Test dictionary with duplicate keys<commit_after>package vm

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

var kvss = [][][2]*Thunk{
	{{True, False}},
	{{Nil, NewNumber(42)}},
	{{False, NewNumber(42)}, {True, NewNumber(13)}},
	{
		{False, NewNumber(42)},
		{True, False},
		{NewNumber(2), NewString("Mr. Value")},
	},
	{
		{NewString("go"), NewList(NewList(), Nil, NewNumber(123))},
		{False, NewNumber(42)},
		{True, False},
		{NewNumber(2), NewString("Mr. Value")},
	},
}

func TestDictionarySet(t *testing.T) {
	for _, k := range []*Thunk{
		True, False, Nil, NewNumber(42), NewString("risp"),
	} {
		_, ok := App(Set, EmptyDictionary, k, Nil).Eval().(dictionaryType)
		assert.True(t, ok)
	}
}

func TestDictionaryGet(t *testing.T) {
	for _, kvs := range kvss {
		d := EmptyDictionary

		for i, kv := range kvs {
			t.Logf("Setting a %vth key...\n", i)
			d = App(Set, d, kv[0], kv[1])
		}

		assert.Equal(t, len(kvs), dictionarySize(d))

		for i, kv := range kvs {
			t.Logf("Getting a %vth value...\n", i)

			k, v := kv[0], kv[1]

			t.Log(k.Eval())

			if e, ok := App(Get, d, k).Eval().(errorType); ok {
				t.Log(e.message.Eval())
			}

			assert.True(t, testEqual(App(Get, d, k), v))
		}
	}
}

func TestDictionaryToList(t *testing.T) {
	for i, kvs := range kvss {
		t.Log("TestDictionaryToList START", i)
		d := EmptyDictionary

		for i, kv := range kvs {
			t.Logf("Setting a %vth key...\n", i)
			d = App(Set, d, kv[0], kv[1])
		}

		assert.Equal(t, len(kvs), dictionarySize(d))

		l := App(ToList, d)

		for i := 0; i < len(kvs); i, l = i+1, App(Rest, l) {
			kv := App(First, l)
			k := App(First, kv)
			lv := App(First, App(Rest, kv))
			dv := App(Get, d, k)

			t.Log("Key:", k.Eval())
			t.Log("LIST Value:", lv.Eval())
			t.Log("DICT Value:", dv.Eval())

			assert.True(t, testEqual(lv, dv))
		}

		assert.Equal(t, l.Eval().(listType), emptyList)
	}
}

func TestDictionaryWithDuplicateKeys(t *testing.T) {
	ks := []*Thunk{
		True, False, Nil, NewNumber(0), NewNumber(1), NewNumber(42),
		NewNumber(2049), NewString("runner"), NewString("lisp"),
	}

	dups := []*Thunk{
		ks[0], ks[1], ks[2], ks[2], ks[7], ks[3], ks[0], ks[4], ks[6], ks[1],
		ks[1], ks[4], ks[5], ks[6], ks[0], ks[2], ks[8], ks[8],
	}

	d := EmptyDictionary

	for _, k := range dups {
		d = App(Set, d, k, k)
	}

	assert.Equal(t, len(ks), dictionarySize(d))

	for _, k := range ks {
		assert.True(t, testEqual(App(Get, d, k), k))
	}
}

func dictionarySize(d *Thunk) int {
	return int(d.Eval().(dictionaryType).hashMap.Size())
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/motemen/ghq/cmdutil"
)

func run(silent bool) func(command string, args ...string) error {
	if silent {
		return cmdutil.RunSilently
	}
	return cmdutil.Run
}

func runInDir(silent bool) func(dir, command string, args ...string) error {
	if silent {
		return cmdutil.RunInDirSilently
	}
	return cmdutil.RunInDir
}

// A VCSBackend represents a VCS backend.
type VCSBackend struct {
	// Clones a remote repository to local path.
	Clone func(*vcsGetOption) error
	// Updates a cloned local repository.
	Update func(*vcsGetOption) error
	Init   func(dir string) error
	// Returns VCS specific files
	Contents []string
}

type vcsGetOption struct {
	url                        *url.URL
	dir                        string
	recursive, shallow, silent bool
	branch                     string
}

// GitBackend is the VCSBackend of git
var GitBackend = &VCSBackend{
	// support submodules?
	Clone: func(vg *vcsGetOption) error {
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		args := []string{"clone"}
		if vg.shallow {
			args = append(args, "--depth", "1")
		}
		if vg.branch != "" {
			args = append(args, "--branch", vg.branch, "--single-branch")
		}
		if vg.recursive {
			args = append(args, "--recursive")
		}
		args = append(args, vg.url.String(), vg.dir)

		return run(vg.silent)("git", args...)
	},
	Update: func(vg *vcsGetOption) error {
		if _, err := os.Stat(filepath.Join(vg.dir, ".git/svn")); err == nil {
			return GitsvnBackend.Update(vg)
		}
		err := runInDir(vg.silent)(vg.dir, "git", "pull", "--ff-only")
		if err != nil {
			return err
		}
		if vg.recursive {
			return runInDir(vg.silent)(vg.dir, "git", "submodule", "update", "--init", "--recursive")
		}
		return nil
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "git", "init")
	},
	Contents: []string{".git"},
}

/*
If the svn target is under standard svn directory structure, "ghq" canonicalizes the checkout path.
For example, all following targets are checked-out into `$(ghq root)/svn.example.com/proj/repo`.

- svn.example.com/proj/repo
- svn.example.com/proj/repo/trunk
- svn.example.com/proj/repo/branches/featureN
- svn.example.com/proj/repo/tags/v1.0.1

Addition, when the svn target may be project root, "ghq" tries to checkout "/trunk".

The checkout rule using "git-svn" also has the same behavior.
*/

const trunk = "/trunk"

var svnReg = regexp.MustCompile(`/(?:tags|branches)/[^/]+$`)

func replaceOnce(reg *regexp.Regexp, str, replace string) string {
	replaced := false
	return reg.ReplaceAllStringFunc(str, func(match string) string {
		if replaced {
			return match
		}
		replaced = true
		return reg.ReplaceAllString(match, replace)
	})
}

func svnBase(p string) string {
	if strings.HasSuffix(p, trunk) {
		return strings.TrimSuffix(p, trunk)
	}
	return replaceOnce(svnReg, p, "")
}

// SubversionBackend is the VCSBackend for subversion
var SubversionBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		vg.dir = svnBase(vg.dir)
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		args := []string{"checkout"}
		if vg.shallow {
			args = append(args, "--depth", "immediates")
		}
		remote := vg.url
		if vg.branch != "" {
			copied := *vg.url
			remote = &copied
			remote.Path = svnBase(remote.Path)
			remote.Path += "/branches/" + url.PathEscape(vg.branch)
		} else if !strings.HasSuffix(remote.Path, trunk) {
			copied := *vg.url
			copied.Path += trunk
			if err := cmdutil.RunSilently("svn", "info", copied.String()); err == nil {
				remote = &copied
			}
		}
		args = append(args, remote.String(), vg.dir)

		return run(vg.silent)("svn", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "svn", "update")
	},
	Contents: []string{".svn"},
}

var svnLastRevReg = regexp.MustCompile(`(?m)^Last Changed Rev: (\d+)$`)

// GitsvnBackend is the VCSBackend for git-svn
var GitsvnBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		orig := vg.dir
		vg.dir = svnBase(vg.dir)
		standard := orig == vg.dir

		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		var getSvnInfo = func(u string) (string, error) {
			buf := &bytes.Buffer{}
			cmd := exec.Command("svn", "info", u)
			cmd.Stdout = buf
			cmd.Stderr = ioutil.Discard
			err := cmdutil.RunCommand(cmd, true)
			return buf.String(), err
		}
		var svnInfo string
		args := []string{"svn", "clone"}
		remote := vg.url
		if vg.branch != "" {
			copied := *remote
			remote = &copied
			remote.Path = svnBase(remote.Path)
			remote.Path += "/branches/" + url.PathEscape(vg.branch)
			standard = false
		} else if standard {
			copied := *remote
			copied.Path += trunk
			info, err := getSvnInfo(copied.String())
			if err == nil {
				args = append(args, "-s")
				svnInfo = info
			} else {
				standard = false
			}
		}

		if vg.shallow {
			if svnInfo == "" {
				info, err := getSvnInfo(remote.String())
				if err != nil {
					return err
				}
				svnInfo = info
			}
			m := svnLastRevReg.FindStringSubmatch(svnInfo)
			if len(m) < 2 {
				return fmt.Errorf("no revisions are taken from svn info output: %s", svnInfo)
			}
			args = append(args, fmt.Sprintf("-r%s:HEAD", m[1]))
		}
		args = append(args, remote.String(), vg.dir)
		return run(vg.silent)("git", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "git", "svn", "rebase")
	},
	Contents: []string{".git/svn"},
}

// MercurialBackend is the VCSBackend for mercurial
var MercurialBackend = &VCSBackend{
	// Mercurial seems not supporting shallow clone currently.
	Clone: func(vg *vcsGetOption) error {
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}
		args := []string{"clone"}
		if vg.branch != "" {
			args = append(args, "--branch", vg.branch)
		}
		args = append(args, vg.url.String(), vg.dir)

		return run(vg.silent)("hg", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "hg", "pull", "--update")
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "hg", "init")
	},
	Contents: []string{".hg"},
}

// DarcsBackend is the VCSBackend for darcs
var DarcsBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		if vg.branch != "" {
			return errors.New("Darcs does not support branch")
		}

		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		args := []string{"get"}
		if vg.shallow {
			args = append(args, "--lazy")
		}
		args = append(args, vg.url.String(), vg.dir)

		return run(vg.silent)("darcs", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "darcs", "pull")
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "darcs", "init")
	},
	Contents: []string{"_darcs"},
}

var cvsDummyBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		return errors.New("CVS clone is not supported")
	},
	Update: func(vg *vcsGetOption) error {
		return errors.New("CVS update is not supported")
	},
	Contents: []string{"CVS/Repository"},
}

const fossilRepoName = ".fossil" // same as Go

// FossilBackend is the VCSBackend for fossil
var FossilBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		if vg.branch != "" {
			return errors.New("Fossil does not support cloning specific branch")
		}
		if err := os.MkdirAll(vg.dir, 0755); err != nil {
			return err
		}

		if err := run(vg.silent)("fossil", "clone", vg.url.String(), filepath.Join(vg.dir, fossilRepoName)); err != nil {
			return err
		}
		return runInDir(vg.silent)(vg.dir, "fossil", "open", fossilRepoName)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "fossil", "update")
	},
	Init: func(dir string) error {
		if err := cmdutil.RunInDirStderr(dir, "fossil", "init", fossilRepoName); err != nil {
			return err
		}
		return cmdutil.RunInDirStderr(dir, "fossil", "open", fossilRepoName)
	},
	Contents: []string{".fslckout", "_FOSSIL_"},
}

// BazaarBackend is the VCSBackend for bazaar
var BazaarBackend = &VCSBackend{
	// bazaar seems not supporting shallow clone currently.
	Clone: func(vg *vcsGetOption) error {
		if vg.branch != "" {
			return errors.New("--branch option is unavailable for Bazaar since branch is included in remote URL")
		}
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}
		return run(vg.silent)("bzr", "branch", vg.url.String(), vg.dir)
	},
	Update: func(vg *vcsGetOption) error {
		// Without --overwrite bzr will not pull tags that changed.
		return runInDir(vg.silent)(vg.dir, "bzr", "pull", "--overwrite")
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "bzr", "init")
	},
	Contents: []string{".bzr"},
}

var vcsRegistry = map[string]*VCSBackend{
	"git":        GitBackend,
	"github":     GitBackend,
	"svn":        SubversionBackend,
	"subversion": SubversionBackend,
	"git-svn":    GitsvnBackend,
	"hg":         MercurialBackend,
	"mercurial":  MercurialBackend,
	"darcs":      DarcsBackend,
	"fossil":     FossilBackend,
	"bzr":        BazaarBackend,
	"bazaar":     BazaarBackend,
}
<commit_msg>adjsut comment<commit_after>package main

import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/motemen/ghq/cmdutil"
)

func run(silent bool) func(command string, args ...string) error {
	if silent {
		return cmdutil.RunSilently
	}
	return cmdutil.Run
}

func runInDir(silent bool) func(dir, command string, args ...string) error {
	if silent {
		return cmdutil.RunInDirSilently
	}
	return cmdutil.RunInDir
}

// A VCSBackend represents a VCS backend.
type VCSBackend struct {
	// Clones a remote repository to local path.
	Clone func(*vcsGetOption) error
	// Updates a cloned local repository.
	Update func(*vcsGetOption) error
	Init   func(dir string) error
	// Returns VCS specific files
	Contents []string
}

type vcsGetOption struct {
	url                        *url.URL
	dir                        string
	recursive, shallow, silent bool
	branch                     string
}

// GitBackend is the VCSBackend of git
var GitBackend = &VCSBackend{
	// support submodules?
	Clone: func(vg *vcsGetOption) error {
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		args := []string{"clone"}
		if vg.shallow {
			args = append(args, "--depth", "1")
		}
		if vg.branch != "" {
			args = append(args, "--branch", vg.branch, "--single-branch")
		}
		if vg.recursive {
			args = append(args, "--recursive")
		}
		args = append(args, vg.url.String(), vg.dir)

		return run(vg.silent)("git", args...)
	},
	Update: func(vg *vcsGetOption) error {
		if _, err := os.Stat(filepath.Join(vg.dir, ".git/svn")); err == nil {
			return GitsvnBackend.Update(vg)
		}
		err := runInDir(vg.silent)(vg.dir, "git", "pull", "--ff-only")
		if err != nil {
			return err
		}
		if vg.recursive {
			return runInDir(vg.silent)(vg.dir, "git", "submodule", "update", "--init", "--recursive")
		}
		return nil
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "git", "init")
	},
	Contents: []string{".git"},
}

/*
If the svn target is under standard svn directory structure, "ghq" canonicalizes the checkout path.
For example, all following targets are checked-out into `$(ghq root)/svn.example.com/proj/repo`.

- svn.example.com/proj/repo
- svn.example.com/proj/repo/trunk
- svn.example.com/proj/repo/branches/featureN
- svn.example.com/proj/repo/tags/v1.0.1

Addition, when the svn target may be project root, "ghq" tries to checkout "/trunk".

This checkout rule is also applied when using "git-svn".
*/

const trunk = "/trunk"

var svnReg = regexp.MustCompile(`/(?:tags|branches)/[^/]+$`)

func replaceOnce(reg *regexp.Regexp, str, replace string) string {
	replaced := false
	return reg.ReplaceAllStringFunc(str, func(match string) string {
		if replaced {
			return match
		}
		replaced = true
		return reg.ReplaceAllString(match, replace)
	})
}

func svnBase(p string) string {
	if strings.HasSuffix(p, trunk) {
		return strings.TrimSuffix(p, trunk)
	}
	return replaceOnce(svnReg, p, "")
}

// SubversionBackend is the VCSBackend for subversion
var SubversionBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		vg.dir = svnBase(vg.dir)
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		args := []string{"checkout"}
		if vg.shallow {
			args = append(args, "--depth", "immediates")
		}
		remote := vg.url
		if vg.branch != "" {
			copied := *vg.url
			remote = &copied
			remote.Path = svnBase(remote.Path)
			remote.Path += "/branches/" + url.PathEscape(vg.branch)
		} else if !strings.HasSuffix(remote.Path, trunk) {
			copied := *vg.url
			copied.Path += trunk
			if err := cmdutil.RunSilently("svn", "info", copied.String()); err == nil {
				remote = &copied
			}
		}
		args = append(args, remote.String(), vg.dir)

		return run(vg.silent)("svn", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "svn", "update")
	},
	Contents: []string{".svn"},
}

var svnLastRevReg = regexp.MustCompile(`(?m)^Last Changed Rev: (\d+)$`)

// GitsvnBackend is the VCSBackend for git-svn
var GitsvnBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		orig := vg.dir
		vg.dir = svnBase(vg.dir)
		standard := orig == vg.dir

		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		var getSvnInfo = func(u string) (string, error) {
			buf := &bytes.Buffer{}
			cmd := exec.Command("svn", "info", u)
			cmd.Stdout = buf
			cmd.Stderr = ioutil.Discard
			err := cmdutil.RunCommand(cmd, true)
			return buf.String(), err
		}
		var svnInfo string
		args := []string{"svn", "clone"}
		remote := vg.url
		if vg.branch != "" {
			copied := *remote
			remote = &copied
			remote.Path = svnBase(remote.Path)
			remote.Path += "/branches/" + url.PathEscape(vg.branch)
			standard = false
		} else if standard {
			copied := *remote
			copied.Path += trunk
			info, err := getSvnInfo(copied.String())
			if err == nil {
				args = append(args, "-s")
				svnInfo = info
			} else {
				standard = false
			}
		}

		if vg.shallow {
			if svnInfo == "" {
				info, err := getSvnInfo(remote.String())
				if err != nil {
					return err
				}
				svnInfo = info
			}
			m := svnLastRevReg.FindStringSubmatch(svnInfo)
			if len(m) < 2 {
				return fmt.Errorf("no revisions are taken from svn info output: %s", svnInfo)
			}
			args = append(args, fmt.Sprintf("-r%s:HEAD", m[1]))
		}
		args = append(args, remote.String(), vg.dir)
		return run(vg.silent)("git", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "git", "svn", "rebase")
	},
	Contents: []string{".git/svn"},
}

// MercurialBackend is the VCSBackend for mercurial
var MercurialBackend = &VCSBackend{
	// Mercurial seems not supporting shallow clone currently.
	Clone: func(vg *vcsGetOption) error {
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}
		args := []string{"clone"}
		if vg.branch != "" {
			args = append(args, "--branch", vg.branch)
		}
		args = append(args, vg.url.String(), vg.dir)

		return run(vg.silent)("hg", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "hg", "pull", "--update")
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "hg", "init")
	},
	Contents: []string{".hg"},
}

// DarcsBackend is the VCSBackend for darcs
var DarcsBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		if vg.branch != "" {
			return errors.New("Darcs does not support branch")
		}

		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}

		args := []string{"get"}
		if vg.shallow {
			args = append(args, "--lazy")
		}
		args = append(args, vg.url.String(), vg.dir)

		return run(vg.silent)("darcs", args...)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "darcs", "pull")
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "darcs", "init")
	},
	Contents: []string{"_darcs"},
}

var cvsDummyBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		return errors.New("CVS clone is not supported")
	},
	Update: func(vg *vcsGetOption) error {
		return errors.New("CVS update is not supported")
	},
	Contents: []string{"CVS/Repository"},
}

const fossilRepoName = ".fossil" // same as Go

// FossilBackend is the VCSBackend for fossil
var FossilBackend = &VCSBackend{
	Clone: func(vg *vcsGetOption) error {
		if vg.branch != "" {
			return errors.New("Fossil does not support cloning specific branch")
		}
		if err := os.MkdirAll(vg.dir, 0755); err != nil {
			return err
		}

		if err := run(vg.silent)("fossil", "clone", vg.url.String(), filepath.Join(vg.dir, fossilRepoName)); err != nil {
			return err
		}
		return runInDir(vg.silent)(vg.dir, "fossil", "open", fossilRepoName)
	},
	Update: func(vg *vcsGetOption) error {
		return runInDir(vg.silent)(vg.dir, "fossil", "update")
	},
	Init: func(dir string) error {
		if err := cmdutil.RunInDirStderr(dir, "fossil", "init", fossilRepoName); err != nil {
			return err
		}
		return cmdutil.RunInDirStderr(dir, "fossil", "open", fossilRepoName)
	},
	Contents: []string{".fslckout", "_FOSSIL_"},
}

// BazaarBackend is the VCSBackend for bazaar
var BazaarBackend = &VCSBackend{
	// bazaar seems not supporting shallow clone currently.
	Clone: func(vg *vcsGetOption) error {
		if vg.branch != "" {
			return errors.New("--branch option is unavailable for Bazaar since branch is included in remote URL")
		}
		dir, _ := filepath.Split(vg.dir)
		err := os.MkdirAll(dir, 0755)
		if err != nil {
			return err
		}
		return run(vg.silent)("bzr", "branch", vg.url.String(), vg.dir)
	},
	Update: func(vg *vcsGetOption) error {
		// Without --overwrite bzr will not pull tags that changed.
		return runInDir(vg.silent)(vg.dir, "bzr", "pull", "--overwrite")
	},
	Init: func(dir string) error {
		return cmdutil.RunInDirStderr(dir, "bzr", "init")
	},
	Contents: []string{".bzr"},
}

var vcsRegistry = map[string]*VCSBackend{
	"git":        GitBackend,
	"github":     GitBackend,
	"svn":        SubversionBackend,
	"subversion": SubversionBackend,
	"git-svn":    GitsvnBackend,
	"hg":         MercurialBackend,
	"mercurial":  MercurialBackend,
	"darcs":      DarcsBackend,
	"fossil":     FossilBackend,
	"bzr":        BazaarBackend,
	"bazaar":     BazaarBackend,
}
<|endoftext|>


<commit_before>package bench

import (
	//"fmt"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
	"testing"

	"github.com/hprose/hprose-go"
	hproserpc "github.com/hprose/hprose-golang/rpc"
)

func hello(name string) string {
	return "Hello " + name + "!"
}

// RO is Reomote object
type RO struct {
	Hello func(string) (string, error)
}

// BenchmarkHprose is ...
func BenchmarkHprose(b *testing.B) {
	b.StopTimer()
	server := hprose.NewTcpServer("")
	server.AddFunction("hello", hello)
	server.Handle()
	client := hprose.NewClient(server.URL)
	var ro *RO
	client.UseService(&ro)
	defer server.Stop()
	// result, _ := ro.Hello("World")
	// fmt.Println(result)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		ro.Hello("World")
	}
}

// BenchmarkHprose2 is ...
func BenchmarkHprose2(b *testing.B) {
	b.StopTimer()
	server := hproserpc.NewTCPServer("")
	server.AddFunction("hello", hello, hproserpc.Options{})
	server.Handle()
	client := hprose.NewClient(server.URI())
	var ro *RO
	client.UseService(&ro)
	defer server.Close()
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		ro.Hello("World")
	}
}

type Args struct {
	Name string
}

type Hello int

func (this *Hello) Hello(args *Args, result *string) error {
	*result = "Hello " + args.Name + "!"
	return nil
}

// BenchmarkGobRPC is ...
func BenchmarkGobRPC(b *testing.B) {
	b.StopTimer()
	server := rpc.NewServer()
	server.Register(new(Hello))
	listener, _ := net.Listen("tcp", "")
	go server.Accept(listener)
	client, _ := rpc.Dial("tcp", listener.Addr().String())
	defer client.Close()
	var args = &Args{"World"}
	var reply string
	// client.Call("Hello.Hello", &args, &reply)
	// fmt.Println(reply)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		client.Call("Hello.Hello", &args, &reply)
	}
}

// BenchmarkJSONRPC is ...
func BenchmarkJSONRPC(b *testing.B) {
	b.StopTimer()
	server := rpc.NewServer()
	server.Register(new(Hello))
	listener, _ := net.Listen("tcp", "")
	go func() {
		for {
			conn, _ := listener.Accept()
			server.ServeCodec(jsonrpc.NewServerCodec(conn))
		}
	}()
	client, _ := jsonrpc.Dial("tcp", listener.Addr().String())
	defer client.Close()
	var args = &Args{"World"}
	var reply string
	// client.Call("Hello.Hello", &args, &reply)
	// fmt.Println(reply)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		client.Call("Hello.Hello", &args, &reply)
	}
}
<commit_msg>Removed unused this<commit_after>package bench

import (
	//"fmt"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
	"testing"

	"github.com/hprose/hprose-go"
	hproserpc "github.com/hprose/hprose-golang/rpc"
)

func hello(name string) string {
	return "Hello " + name + "!"
}

// RO is Reomote object
type RO struct {
	Hello func(string) (string, error)
}

// BenchmarkHprose is ...
func BenchmarkHprose(b *testing.B) {
	b.StopTimer()
	server := hprose.NewTcpServer("")
	server.AddFunction("hello", hello)
	server.Handle()
	client := hprose.NewClient(server.URL)
	var ro *RO
	client.UseService(&ro)
	defer server.Stop()
	// result, _ := ro.Hello("World")
	// fmt.Println(result)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		ro.Hello("World")
	}
}

// BenchmarkHprose2 is ...
func BenchmarkHprose2(b *testing.B) {
	b.StopTimer()
	server := hproserpc.NewTCPServer("")
	server.AddFunction("hello", hello, hproserpc.Options{})
	server.Handle()
	client := hprose.NewClient(server.URI())
	var ro *RO
	client.UseService(&ro)
	defer server.Close()
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		ro.Hello("World")
	}
}

type Args struct {
	Name string
}

type Hello int

func (*Hello) Hello(args *Args, result *string) error {
	*result = "Hello " + args.Name + "!"
	return nil
}

// BenchmarkGobRPC is ...
func BenchmarkGobRPC(b *testing.B) {
	b.StopTimer()
	server := rpc.NewServer()
	server.Register(new(Hello))
	listener, _ := net.Listen("tcp", "")
	go server.Accept(listener)
	client, _ := rpc.Dial("tcp", listener.Addr().String())
	defer client.Close()
	var args = &Args{"World"}
	var reply string
	// client.Call("Hello.Hello", &args, &reply)
	// fmt.Println(reply)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		client.Call("Hello.Hello", &args, &reply)
	}
}

// BenchmarkJSONRPC is ...
func BenchmarkJSONRPC(b *testing.B) {
	b.StopTimer()
	server := rpc.NewServer()
	server.Register(new(Hello))
	listener, _ := net.Listen("tcp", "")
	go func() {
		for {
			conn, _ := listener.Accept()
			server.ServeCodec(jsonrpc.NewServerCodec(conn))
		}
	}()
	client, _ := jsonrpc.Dial("tcp", listener.Addr().String())
	defer client.Close()
	var args = &Args{"World"}
	var reply string
	// client.Call("Hello.Hello", &args, &reply)
	// fmt.Println(reply)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		client.Call("Hello.Hello", &args, &reply)
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 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 tar_test

import (
	"archive/tar"
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
)

func Example() {
	// Create a buffer to write our archive to.
	buf := new(bytes.Buffer)

	// Create a new tar archive.
	tw := tar.NewWriter(buf)

	// Add some files to the archive.
	var files = []struct {
		Name, Body string
	}{
		{"readme.txt", "This archive contains some text files."},
		{"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
		{"todo.txt", "Get animal handling licence."},
	}
	for _, file := range files {
		hdr := &tar.Header{
			Name: file.Name,
			Mode: 0600,
			Size: int64(len(file.Body)),
		}
		if err := tw.WriteHeader(hdr); err != nil {
			log.Fatalln(err)
		}
		if _, err := tw.Write([]byte(file.Body)); err != nil {
			log.Fatalln(err)
		}
	}
	// Make sure to check the error on Close.
	if err := tw.Close(); err != nil {
		log.Fatalln(err)
	}

	// Open the tar archive for reading.
	r := bytes.NewReader(buf.Bytes())
	tr := tar.NewReader(r)

	// Iterate through the files in the archive.
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			// end of tar archive
			break
		}
		if err != nil {
			log.Fatalln(err)
		}
		fmt.Printf("Contents of %s:\n", hdr.Name)
		if _, err := io.Copy(os.Stdout, tr); err != nil {
			log.Fatalln(err)
		}
		fmt.Println()
	}

	// Output:
	// Contents of readme.txt:
	// This archive contains some text files.
	// Contents of gopher.txt:
	// Gopher names:
	// George
	// Geoffrey
	// Gonzo
	// Contents of todo.txt:
	// Get animal handling licence.
}
<commit_msg>archive/tar: spell license correctly in example<commit_after>// Copyright 2013 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 tar_test

import (
	"archive/tar"
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
)

func Example() {
	// Create a buffer to write our archive to.
	buf := new(bytes.Buffer)

	// Create a new tar archive.
	tw := tar.NewWriter(buf)

	// Add some files to the archive.
	var files = []struct {
		Name, Body string
	}{
		{"readme.txt", "This archive contains some text files."},
		{"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"},
		{"todo.txt", "Get animal handling license."},
	}
	for _, file := range files {
		hdr := &tar.Header{
			Name: file.Name,
			Mode: 0600,
			Size: int64(len(file.Body)),
		}
		if err := tw.WriteHeader(hdr); err != nil {
			log.Fatalln(err)
		}
		if _, err := tw.Write([]byte(file.Body)); err != nil {
			log.Fatalln(err)
		}
	}
	// Make sure to check the error on Close.
	if err := tw.Close(); err != nil {
		log.Fatalln(err)
	}

	// Open the tar archive for reading.
	r := bytes.NewReader(buf.Bytes())
	tr := tar.NewReader(r)

	// Iterate through the files in the archive.
	for {
		hdr, err := tr.Next()
		if err == io.EOF {
			// end of tar archive
			break
		}
		if err != nil {
			log.Fatalln(err)
		}
		fmt.Printf("Contents of %s:\n", hdr.Name)
		if _, err := io.Copy(os.Stdout, tr); err != nil {
			log.Fatalln(err)
		}
		fmt.Println()
	}

	// Output:
	// Contents of readme.txt:
	// This archive contains some text files.
	// Contents of gopher.txt:
	// Gopher names:
	// George
	// Geoffrey
	// Gonzo
	// Contents of todo.txt:
	// Get animal handling license.
}
<|endoftext|>