<commit_before>package paypal

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

const (
	NVP_SANDBOX_URL         = "https://api-3t.sandbox.paypal.com/nvp"
	NVP_PRODUCTION_URL      = "https://api-3t.paypal.com/nvp"
	CHECKOUT_SANDBOX_URL    = "https://www.sandbox.paypal.com/cgi-bin/webscr"
	CHECKOUT_PRODUCTION_URL = "https://www.paypal.com/cgi-bin/webscr"
	NVP_VERSION             = "84"
)

type PayPalClient struct {
	username    string
	password    string
	signature   string
	endpoint    string
	usesSandbox bool
	client      *http.Client
}

type PayPalDigitalGood struct {
	Name     string
	Amount   float64
	Quantity int16
}

type PayPalResponse struct {
	Ack           string
	CorrelationId string
	Timestamp     string
	Version       string
	Build         string
	Values        url.Values
	usedSandbox   bool
}

type PayPalError struct {
	Ack          string
	ErrorCode    string
	ShortMessage string
	LongMessage  string
	SeverityCode string
}

func (e *PayPalError) Error() string {
	var message string
	if len(e.ErrorCode) != 0 && len(e.ShortMessage) != 0 {
		message = "PayPal Error " + e.ErrorCode + ": " + e.ShortMessage
	} else if len(e.Ack) != 0 {
		message = e.Ack
	} else {
		message = "PayPal is undergoing maintenance.\nPlease try again later."
	}

	return message
}

func (r *PayPalResponse) CheckoutUrl() string {
	query := url.Values{}
	query.Set("cmd", "_express-checkout")
	query.Add("token", r.Values["TOKEN"][0])
	checkoutUrl := CHECKOUT_PRODUCTION_URL
	if r.usedSandbox {
		checkoutUrl = CHECKOUT_SANDBOX_URL
	}
	return fmt.Sprintf("%s?%s", checkoutUrl, query.Encode())
}

func SumPayPalDigitalGoodAmounts(goods *[]PayPalDigitalGood) (sum float64) {
	for _, dg := range *goods {
		sum += dg.Amount * float64(dg.Quantity)
	}
	return
}

func NewDefaultClientEndpoint(username, password, signature, endpoint string, usesSandbox bool) *PayPalClient {
	return &PayPalClient{
		username:    username,
		password:    password,
		signature:   signature,
		endpoint:    endpoint,
		usesSandbox: usesSandbox,
		client:      new(http.Client),
	}
}

func NewDefaultClient(username, password, signature string, usesSandbox bool) *PayPalClient {
	var endpoint = NVP_PRODUCTION_URL
	if usesSandbox {
		endpoint = NVP_SANDBOX_URL
	}

	return &PayPalClient{
		username:    username,
		password:    password,
		signature:   signature,
		endpoint:    endpoint,
		usesSandbox: usesSandbox,
		client:      new(http.Client),
	}
}

func NewClient(username, password, signature string, usesSandbox bool, client *http.Client) *PayPalClient {
	var endpoint = NVP_PRODUCTION_URL
	if usesSandbox {
		endpoint = NVP_SANDBOX_URL
	}

	return &PayPalClient{
		username:    username,
		password:    password,
		signature:   signature,
		endpoint:    endpoint,
		usesSandbox: usesSandbox,
		client:      client,
	}
}

func (pClient *PayPalClient) PerformRequest(values url.Values) (*PayPalResponse, error) {
	values.Add("USER", pClient.username)
	values.Add("PWD", pClient.password)
	values.Add("SIGNATURE", pClient.signature)
	values.Add("VERSION", NVP_VERSION)

	formResponse, err := pClient.client.PostForm(pClient.endpoint, values)
	if err != nil {
		return nil, err
	}
	defer formResponse.Body.Close()

	body, err := ioutil.ReadAll(formResponse.Body)
	if err != nil {
		return nil, err
	}

	responseValues, err := url.ParseQuery(string(body))
	response := &PayPalResponse{usedSandbox: pClient.usesSandbox}
	if err == nil {
		response.Ack = responseValues.Get("ACK")
		response.CorrelationId = responseValues.Get("CORRELATIONID")
		response.Timestamp = responseValues.Get("TIMESTAMP")
		response.Version = responseValues.Get("VERSION")
		response.Build = responseValues.Get("2975009")
		response.Values = responseValues

		errorCode := responseValues.Get("L_ERRORCODE0")
		if len(errorCode) != 0 || strings.ToLower(response.Ack) == "failure" || strings.ToLower(response.Ack) == "failurewithwarning" {
			pError := new(PayPalError)
			pError.Ack = response.Ack
			pError.ErrorCode = errorCode
			pError.ShortMessage = responseValues.Get("L_SHORTMESSAGE0")
			pError.LongMessage = responseValues.Get("L_LONGMESSAGE0")
			pError.SeverityCode = responseValues.Get("L_SEVERITYCODE0")

			err = pError
		}
	}

	return response, err
}

func (pClient *PayPalClient) SetExpressCheckoutDigitalGoods(paymentAmount float64, currencyCode string, returnURL, cancelURL string, goods []PayPalDigitalGood) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "SetExpressCheckout")
	values.Add("PAYMENTREQUEST_0_AMT", fmt.Sprintf("%.2f", paymentAmount))
	values.Add("PAYMENTREQUEST_0_PAYMENTACTION", "Sale")
	values.Add("PAYMENTREQUEST_0_CURRENCYCODE", currencyCode)
	values.Add("RETURNURL", returnURL)
	values.Add("CANCELURL", cancelURL)
	values.Add("REQCONFIRMSHIPPING", "0")
	values.Add("NOSHIPPING", "1")
	values.Add("SOLUTIONTYPE", "Sole")

	for i := 0; i < len(goods); i++ {
		good := goods[i]

		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_NAME", i), good.Name)
		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_AMT", i), fmt.Sprintf("%.2f", good.Amount))
		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_QTY", i), fmt.Sprintf("%d", good.Quantity))
		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_ITEMCATEGORY", i), "Digital")
	}

	return pClient.PerformRequest(values)
}

// Convenience function for Sale (Charge)
func (pClient *PayPalClient) DoExpressCheckoutSale(token, payerId, currencyCode string, finalPaymentAmount float64) (*PayPalResponse, error) {
	return pClient.DoExpressCheckoutPayment(token, payerId, "Sale", currencyCode, finalPaymentAmount)
}

// paymentType can be "Sale" or "Authorization" or "Order" (ship later)
func (pClient *PayPalClient) DoExpressCheckoutPayment(token, payerId, paymentType, currencyCode string, finalPaymentAmount float64) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "DoExpressCheckoutPayment")
	values.Add("TOKEN", token)
	values.Add("PAYERID", payerId)
	values.Add("PAYMENTREQUEST_0_PAYMENTACTION", paymentType)
	values.Add("PAYMENTREQUEST_0_CURRENCYCODE", currencyCode)
	values.Add("PAYMENTREQUEST_0_AMT", fmt.Sprintf("%.2f", finalPaymentAmount))

	return pClient.PerformRequest(values)
}

func (pClient *PayPalClient) GetExpressCheckoutDetails(token string) (*PayPalResponse, error) {
	values := url.Values{}
	values.Add("TOKEN", token)
	values.Set("METHOD", "GetExpressCheckoutDetails")
	return pClient.PerformRequest(values)
}

//----------------------------------------------------------
// Forked
//----------------------------------------------------------

func (pClient *PayPalClient) CreateRecurringPaymentsProfile(token string, params map[string]string) (*PayPalResponse, error) {
	values := url.Values{}
	values.Add("TOKEN", token)
	values.Set("METHOD", "CreateRecurringPaymentsProfile")

	if params != nil {
		for key, value := range params {
			values.Add(key, value)
		}
	}

	return pClient.PerformRequest(values)
}

func (pClient *PayPalClient) BillOutstandingAmount(profileId string) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "BillOutstandingAmount")
	values.Set("PROFILEID", profileId)

	return pClient.PerformRequest(values)
}

func NewDigitalGood(name string, amount float64) *PayPalDigitalGood {
	return &PayPalDigitalGood{
		Name:     name,
		Amount:   amount,
		Quantity: 1,
	}
}

type ExpressCheckoutSingleArgs struct {
	Amount                             float64
	CurrencyCode, ReturnURL, CancelURL string
	Recurring                          bool
	Item                               *PayPalDigitalGood
}

func NewExpressCheckoutSingleArgs() *ExpressCheckoutSingleArgs {
	return &ExpressCheckoutSingleArgs{
		Amount:       0,
		CurrencyCode: "USD",
		Recurring:    true,
	}
}

func (pClient *PayPalClient) SetExpressCheckoutSingle(args *ExpressCheckoutSingleArgs) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "SetExpressCheckout")
	values.Add("PAYMENTREQUEST_0_AMT", fmt.Sprintf("%.2f", args.Amount))
	values.Add("NOSHIPPING", "1")

	values.Add("L_PAYMENTREQUEST_0_NAME0", args.Item.Name)
	values.Add("L_BILLINGTYPE0", "RecurringPayments")
	values.Add("L_BILLINGAGREEMENTDESCRIPTION0", args.Item.Name)
	values.Add("L_PAYMENTTYPE0", "InstantOnly")

	values.Add("RETURNURL", args.ReturnURL)
	values.Add("CANCELURL", args.CancelURL)

	return pClient.PerformRequest(values)
}

type Action string

const (
	Cancel     Action = "Cancel"
	Suspend    Action = "Suspend"
	Reactivate Action = "Reactivate"
)

func (pClient *PayPalClient) ManageRecurringPaymentsProfileStatus(profileId string, action Action) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "ManageRecurringPaymentsProfileStatus")
	values.Set("PROFILEID", profileId)
	values.Set("ACTION", string(action))

	return pClient.PerformRequest(values)
}
<commit_msg>payment: update paypal library<commit_after>package paypal

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
)

const (
	NVP_SANDBOX_URL         = "https://api-3t.sandbox.paypal.com/nvp"
	NVP_PRODUCTION_URL      = "https://api-3t.paypal.com/nvp"
	CHECKOUT_SANDBOX_URL    = "https://www.sandbox.paypal.com/cgi-bin/webscr"
	CHECKOUT_PRODUCTION_URL = "https://www.paypal.com/cgi-bin/webscr"
	NVP_VERSION             = "84"
)

type PayPalClient struct {
	username    string
	password    string
	signature   string
	endpoint    string
	usesSandbox bool
	client      *http.Client
}

type PayPalDigitalGood struct {
	Name     string
	Amount   float64
	Quantity int16
}

type PayPalResponse struct {
	Ack           string
	CorrelationId string
	Timestamp     string
	Version       string
	Build         string
	Values        url.Values
	usedSandbox   bool
}

type PayPalError struct {
	Ack          string
	ErrorCode    string
	ShortMessage string
	LongMessage  string
	SeverityCode string
}

func (e *PayPalError) Error() string {
	var message string
	if len(e.ErrorCode) != 0 && len(e.ShortMessage) != 0 {
		message = "PayPal Error " + e.ErrorCode + ": " + e.ShortMessage
	} else if len(e.Ack) != 0 {
		message = e.Ack
	} else {
		message = "PayPal is undergoing maintenance.\nPlease try again later."
	}

	return message
}

func (r *PayPalResponse) CheckoutUrl() string {
	query := url.Values{}
	query.Set("cmd", "_express-checkout")
	query.Add("token", r.Values["TOKEN"][0])
	checkoutUrl := CHECKOUT_PRODUCTION_URL
	if r.usedSandbox {
		checkoutUrl = CHECKOUT_SANDBOX_URL
	}
	return fmt.Sprintf("%s?%s", checkoutUrl, query.Encode())
}

func SumPayPalDigitalGoodAmounts(goods *[]PayPalDigitalGood) (sum float64) {
	for _, dg := range *goods {
		sum += dg.Amount * float64(dg.Quantity)
	}
	return
}

func NewDefaultClientEndpoint(username, password, signature, endpoint string, usesSandbox bool) *PayPalClient {
	return &PayPalClient{
		username:    username,
		password:    password,
		signature:   signature,
		endpoint:    endpoint,
		usesSandbox: usesSandbox,
		client:      new(http.Client),
	}
}

func NewDefaultClient(username, password, signature string, usesSandbox bool) *PayPalClient {
	var endpoint = NVP_PRODUCTION_URL
	if usesSandbox {
		endpoint = NVP_SANDBOX_URL
	}

	return &PayPalClient{
		username:    username,
		password:    password,
		signature:   signature,
		endpoint:    endpoint,
		usesSandbox: usesSandbox,
		client:      new(http.Client),
	}
}

func NewClient(username, password, signature string, usesSandbox bool, client *http.Client) *PayPalClient {
	var endpoint = NVP_PRODUCTION_URL
	if usesSandbox {
		endpoint = NVP_SANDBOX_URL
	}

	return &PayPalClient{
		username:    username,
		password:    password,
		signature:   signature,
		endpoint:    endpoint,
		usesSandbox: usesSandbox,
		client:      client,
	}
}

func (pClient *PayPalClient) PerformRequest(values url.Values) (*PayPalResponse, error) {
	values.Add("USER", pClient.username)
	values.Add("PWD", pClient.password)
	values.Add("SIGNATURE", pClient.signature)
	values.Add("VERSION", NVP_VERSION)

	formResponse, err := pClient.client.PostForm(pClient.endpoint, values)
	if err != nil {
		return nil, err
	}
	defer formResponse.Body.Close()

	body, err := ioutil.ReadAll(formResponse.Body)
	if err != nil {
		return nil, err
	}

	responseValues, err := url.ParseQuery(string(body))
	response := &PayPalResponse{usedSandbox: pClient.usesSandbox}
	if err == nil {
		response.Ack = responseValues.Get("ACK")
		response.CorrelationId = responseValues.Get("CORRELATIONID")
		response.Timestamp = responseValues.Get("TIMESTAMP")
		response.Version = responseValues.Get("VERSION")
		response.Build = responseValues.Get("2975009")
		response.Values = responseValues

		errorCode := responseValues.Get("L_ERRORCODE0")
		if len(errorCode) != 0 || strings.ToLower(response.Ack) == "failure" || strings.ToLower(response.Ack) == "failurewithwarning" {
			pError := new(PayPalError)
			pError.Ack = response.Ack
			pError.ErrorCode = errorCode
			pError.ShortMessage = responseValues.Get("L_SHORTMESSAGE0")
			pError.LongMessage = responseValues.Get("L_LONGMESSAGE0")
			pError.SeverityCode = responseValues.Get("L_SEVERITYCODE0")

			err = pError
		}
	}

	return response, err
}

func (pClient *PayPalClient) SetExpressCheckoutDigitalGoods(paymentAmount float64, currencyCode string, returnURL, cancelURL string, goods []PayPalDigitalGood) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "SetExpressCheckout")
	values.Add("PAYMENTREQUEST_0_AMT", fmt.Sprintf("%.2f", paymentAmount))
	values.Add("PAYMENTREQUEST_0_PAYMENTACTION", "Sale")
	values.Add("PAYMENTREQUEST_0_CURRENCYCODE", currencyCode)
	values.Add("RETURNURL", returnURL)
	values.Add("CANCELURL", cancelURL)
	values.Add("REQCONFIRMSHIPPING", "0")
	values.Add("NOSHIPPING", "1")
	values.Add("SOLUTIONTYPE", "Sole")

	for i := 0; i < len(goods); i++ {
		good := goods[i]

		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_NAME", i), good.Name)
		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_AMT", i), fmt.Sprintf("%.2f", good.Amount))
		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_QTY", i), fmt.Sprintf("%d", good.Quantity))
		values.Add(fmt.Sprintf("%s%d", "L_PAYMENTREQUEST_0_ITEMCATEGORY", i), "Digital")
	}

	return pClient.PerformRequest(values)
}

// Convenience function for Sale (Charge)
func (pClient *PayPalClient) DoExpressCheckoutSale(token, payerId, currencyCode string, finalPaymentAmount float64) (*PayPalResponse, error) {
	return pClient.DoExpressCheckoutPayment(token, payerId, "Sale", currencyCode, finalPaymentAmount)
}

// paymentType can be "Sale" or "Authorization" or "Order" (ship later)
func (pClient *PayPalClient) DoExpressCheckoutPayment(token, payerId, paymentType, currencyCode string, finalPaymentAmount float64) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "DoExpressCheckoutPayment")
	values.Add("TOKEN", token)
	values.Add("PAYERID", payerId)
	values.Add("PAYMENTREQUEST_0_PAYMENTACTION", paymentType)
	values.Add("PAYMENTREQUEST_0_CURRENCYCODE", currencyCode)
	values.Add("PAYMENTREQUEST_0_AMT", fmt.Sprintf("%.2f", finalPaymentAmount))

	return pClient.PerformRequest(values)
}

func (pClient *PayPalClient) GetExpressCheckoutDetails(token string) (*PayPalResponse, error) {
	values := url.Values{}
	values.Add("TOKEN", token)
	values.Set("METHOD", "GetExpressCheckoutDetails")
	return pClient.PerformRequest(values)
}

//----------------------------------------------------------
// Forked
//----------------------------------------------------------

func (pClient *PayPalClient) CreateRecurringPaymentsProfile(token string, params map[string]string) (*PayPalResponse, error) {
	values := url.Values{}
	values.Add("TOKEN", token)
	values.Set("METHOD", "CreateRecurringPaymentsProfile")

	if params != nil {
		for key, value := range params {
			values.Add(key, value)
		}
	}

	return pClient.PerformRequest(values)
}

func (pClient *PayPalClient) BillOutstandingAmount(profileId string) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "BillOutstandingAmount")
	values.Set("PROFILEID", profileId)

	return pClient.PerformRequest(values)
}

func NewDigitalGood(name string, amount float64) *PayPalDigitalGood {
	return &PayPalDigitalGood{
		Name:     name,
		Amount:   amount,
		Quantity: 1,
	}
}

type ExpressCheckoutSingleArgs struct {
	Amount                             float64
	CurrencyCode, ReturnURL, CancelURL string
	Recurring                          bool
	Item                               *PayPalDigitalGood
}

func NewExpressCheckoutSingleArgs() *ExpressCheckoutSingleArgs {
	return &ExpressCheckoutSingleArgs{
		Amount:       0,
		CurrencyCode: "USD",
		Recurring:    true,
	}
}

func (pClient *PayPalClient) SetExpressCheckoutSingle(args *ExpressCheckoutSingleArgs) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "SetExpressCheckout")
	values.Add("PAYMENTREQUEST_0_AMT", fmt.Sprintf("%.2f", args.Amount))
	values.Add("NOSHIPPING", "1")

	values.Add("L_PAYMENTREQUEST_0_NAME0", args.Item.Name)
	values.Add("L_BILLINGTYPE0", "RecurringPayments")
	values.Add("L_BILLINGAGREEMENTDESCRIPTION0", args.Item.Name)
	values.Add("L_PAYMENTTYPE0", "InstantOnly")

	values.Add("RETURNURL", args.ReturnURL)
	values.Add("CANCELURL", args.CancelURL)

	return pClient.PerformRequest(values)
}

type Action string

const (
	Cancel     Action = "Cancel"
	Suspend    Action = "Suspend"
	Reactivate Action = "Reactivate"
)

func (pClient *PayPalClient) ManageRecurringPaymentsProfileStatus(profileId string, action Action) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "ManageRecurringPaymentsProfileStatus")
	values.Set("PROFILEID", profileId)
	values.Set("ACTION", string(action))

	return pClient.PerformRequest(values)
}

func (pClient *PayPalClient) UpdateRecurringPaymentsProfile(profileId string, params map[string]string) (*PayPalResponse, error) {
	values := url.Values{}
	values.Set("METHOD", "UpdateRecurringPaymentsProfile")
	values.Set("PROFILEID", profileId)

	if params != nil {
		for key, value := range params {
			values.Add(key, value)
		}
	}

	return pClient.PerformRequest(values)
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"time"
)

type ChannelMessage struct {
	// unique identifier of the channel message
	Id int64

	// Body of the mesage
	Body string

	// type of the message
	Type string

	// Creator of the channel message
	AccountId int64

	// Creation date of the message
	CreatedAt time.Time

	// Modification date of the message
	UpdatedAt time.Time
	m         Model
}

func (c *ChannelMessage) GetId() int64 {
	return c.Id
}

func (c *ChannelMessage) TableName() string {
	return "channel_message"
}

func (c *ChannelMessage) Self() Modellable {
	return c
}

const (
	ChannelMessage_TYPE_POST  = "post"
	ChannelMessage_TYPE_JOIN  = "join"
	ChannelMessage_TYPE_LEAVE = "leave"
	ChannelMessage_TYPE_CHAT  = "chat"
)

func NewChannelMessage() *ChannelMessage {
	return &ChannelMessage{}
}

func (c *ChannelMessage) Fetch() error {
	return c.m.Fetch(c)
}

func (c *ChannelMessage) Update() error {
	// only update body
	return c.m.UpdatePartial(c,
		map[string]interface{}{
			"body": c.Body,
		},
	)
}

func (c *ChannelMessage) Create() error {
	return c.m.Create(c)
}

func (c *ChannelMessage) Delete() error {
	return c.m.Delete(c)
}

func (c *ChannelMessage) FetchByIds(ids []int64) ([]ChannelMessage, error) {
	var messages []ChannelMessage

	if len(ids) == 0 {
		return messages, nil
	}

	if err := c.m.FetchByIds(c, &messages, ids); err != nil {
		return nil, err
	}
	return messages, nil
}

func (c *ChannelMessage) FetchRelatives() (*ChannelMessageContainer, error) {
	if c.Id == 0 {
		return nil, errors.New("Channel message id is not set")
	}
	container := NewChannelMessageContainer()
	container.Message = c

	i := NewInteraction()
	i.MessageId = c.Id

	interactions, err := i.List("like")
	if err != nil {
		return nil, err
	}

	interactionContainer := NewInteractionContainer()
	interactionContainer.Actors = interactions
	// check this from database
	interactionContainer.IsInteracted = true

	if container.Interactions == nil {
		container.Interactions = make(map[string]*InteractionContainer)
	}
	if _, ok := container.Interactions["like"]; !ok {
		container.Interactions["like"] = NewInteractionContainer()
	}
	container.Interactions["like"] = interactionContainer
	return container, nil
}
<commit_msg>Social: implement plugin functions for ChannelMesage<commit_after>package models

import (
	"errors"
	"time"
)

type ChannelMessage struct {
	// unique identifier of the channel message
	Id int64

	// Body of the mesage
	Body string

	// type of the message
	Type string

	// Creator of the channel message
	AccountId int64

	// Creation date of the message
	CreatedAt time.Time

	// Modification date of the message
	UpdatedAt time.Time
	m         Model
}

func (c *ChannelMessage) AfterCreate() {
	c.m.AfterCreate(c)
}

func (c *ChannelMessage) AfterUpdate() {
	c.m.AfterUpdate(c)
}

func (c *ChannelMessage) AfterDelete() {
	c.m.AfterDelete(c)
}

func (c *ChannelMessage) GetId() int64 {
	return c.Id
}

func (c *ChannelMessage) TableName() string {
	return "channel_message"
}

func (c *ChannelMessage) Self() Modellable {
	return c
}

const (
	ChannelMessage_TYPE_POST  = "post"
	ChannelMessage_TYPE_JOIN  = "join"
	ChannelMessage_TYPE_LEAVE = "leave"
	ChannelMessage_TYPE_CHAT  = "chat"
)

func NewChannelMessage() *ChannelMessage {
	return &ChannelMessage{}
}

func (c *ChannelMessage) Fetch() error {
	return c.m.Fetch(c)
}

func (c *ChannelMessage) Update() error {
	// only update body
	return c.m.UpdatePartial(c,
		map[string]interface{}{
			"body": c.Body,
		},
	)
}

func (c *ChannelMessage) Create() error {
	return c.m.Create(c)
}

func (c *ChannelMessage) Delete() error {
	return c.m.Delete(c)
}

func (c *ChannelMessage) FetchByIds(ids []int64) ([]ChannelMessage, error) {
	var messages []ChannelMessage

	if len(ids) == 0 {
		return messages, nil
	}

	if err := c.m.FetchByIds(c, &messages, ids); err != nil {
		return nil, err
	}
	return messages, nil
}

func (c *ChannelMessage) FetchRelatives() (*ChannelMessageContainer, error) {
	if c.Id == 0 {
		return nil, errors.New("Channel message id is not set")
	}
	container := NewChannelMessageContainer()
	container.Message = c

	i := NewInteraction()
	i.MessageId = c.Id

	interactions, err := i.List("like")
	if err != nil {
		return nil, err
	}

	interactionContainer := NewInteractionContainer()
	interactionContainer.Actors = interactions
	// check this from database
	interactionContainer.IsInteracted = true

	if container.Interactions == nil {
		container.Interactions = make(map[string]*InteractionContainer)
	}
	if _, ok := container.Interactions["like"]; !ok {
		container.Interactions["like"] = NewInteractionContainer()
	}
	container.Interactions["like"] = interactionContainer
	return container, nil
}
<|endoftext|>


<commit_before>package bip38

import (
	"bytes"
	"crypto/aes"
	"crypto/sha256"
	"encoding/hex"
	"log"
	"math/big"

	"golang.org/x/crypto/scrypt"

	"github.com/piotrnar/gocoin/lib/btc"
)

func sha256Twice(b []byte) []byte {
	h := sha256.New()
	h.Write(b)
	hashedOnce := h.Sum(nil)
	h.Reset()
	h.Write(hashedOnce)
	return h.Sum(nil)
}

func DecryptWithPassphrase(encryptedKey string, passphrase string) string {
	dec := btc.Decodeb58(encryptedKey)[:39] // trim to length 39 (not sure why needed)
	if dec == nil {
		log.Fatal("Cannot decode base58 string " + encryptedKey)
	}

	if dec[0] == 0x01 && dec[1] == 0x42 {
		log.Fatal("TODO: implement decryption when EC multiply mode not used")
	} else if dec[0] == 0x01 && dec[1] == 0x43 {
		compress := dec[2]&0x20 == 0x20
		hasLotSequence := dec[2]&0x04 == 0x04

		var ownerSalt, ownerEntropy []byte
		if hasLotSequence {
			ownerSalt = dec[7:11]
			ownerEntropy = dec[7:15]
		} else {
			ownerSalt = dec[7:15]
			ownerEntropy = ownerSalt
		}

		prefactorA, err := scrypt.Key([]byte(passphrase), ownerSalt, 16384, 8, 8, 32)
		if prefactorA == nil {
			log.Fatal(err)
		}

		var passFactor []byte
		if hasLotSequence {
			prefactorB := bytes.Join([][]byte{prefactorA, ownerEntropy}, nil)
			passFactor = sha256Twice(prefactorB)
		} else {
			passFactor = prefactorA
		}

		passpoint, err := btc.PublicFromPrivate(passFactor, true)
		if passpoint == nil {
			log.Fatal(err)
		}

		encryptedpart1 := dec[15:23]
		encryptedpart2 := dec[23:39]

		derived, err := scrypt.Key(passpoint, bytes.Join([][]byte{dec[3:7], ownerEntropy}, nil), 1024, 1, 1, 64)
		if derived == nil {
			log.Fatal(err)
		}

		h, err := aes.NewCipher(derived[32:])
		if h == nil {
			log.Fatal(err)
		}

		unencryptedpart2 := make([]byte, 16)
		h.Decrypt(unencryptedpart2, encryptedpart2)
		for i := range unencryptedpart2 {
			unencryptedpart2[i] ^= derived[i+16]
		}

		encryptedpart1 = bytes.Join([][]byte{encryptedpart1, unencryptedpart2[:8]}, nil)

		unencryptedpart1 := make([]byte, 16)
		h.Decrypt(unencryptedpart1, encryptedpart1)
		for i := range unencryptedpart1 {
			unencryptedpart1[i] ^= derived[i]
		}

		seeddb := bytes.Join([][]byte{unencryptedpart1[:16], unencryptedpart2[8:]}, nil)
		factorb := sha256Twice(seeddb)

		bigN, success := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
		if !success {
			log.Fatal("Failed to create Int for N")
		}

		passFactorBig := new(big.Int).SetBytes(passFactor)
		factorbBig := new(big.Int).SetBytes(factorb)

		privKey := new(big.Int)
		privKey.Mul(passFactorBig, factorbBig)
		privKey.Mod(privKey, bigN)

		pubKey, err := btc.PublicFromPrivate(privKey.Bytes(), compress)
		if pubKey == nil {
			log.Fatal(err)
		}

		addr := btc.NewAddrFromPubkey(pubKey, 0).String()

		addrHashed := sha256Twice([]byte(addr))

		if addrHashed[0] != dec[3] || addrHashed[1] != dec[4] || addrHashed[2] != dec[5] || addrHashed[3] != dec[6] {
			return ""
		}

		return hex.EncodeToString(privKey.Bytes())
	}

	log.Fatal("Malformed byte slice")
	return ""
}
<commit_msg>fix 2:=1<commit_after>package bip38

import (
	"bytes"
	"crypto/aes"
	"crypto/sha256"
	"encoding/hex"
	"log"
	"math/big"

	"golang.org/x/crypto/scrypt"

	"github.com/piotrnar/gocoin/lib/btc"
)

func sha256Twice(b []byte) []byte {
	h := sha256.New()
	h.Write(b)
	hashedOnce := h.Sum(nil)
	h.Reset()
	h.Write(hashedOnce)
	return h.Sum(nil)
}

func DecryptWithPassphrase(encryptedKey string, passphrase string) string {
	dec := btc.Decodeb58(encryptedKey)[:39] // trim to length 39 (not sure why needed)
	if dec == nil {
		log.Fatal("Cannot decode base58 string " + encryptedKey)
	}

	if dec[0] == 0x01 && dec[1] == 0x42 {
		log.Fatal("TODO: implement decryption when EC multiply mode not used")
	} else if dec[0] == 0x01 && dec[1] == 0x43 {
		compress := dec[2]&0x20 == 0x20
		hasLotSequence := dec[2]&0x04 == 0x04

		var ownerSalt, ownerEntropy []byte
		if hasLotSequence {
			ownerSalt = dec[7:11]
			ownerEntropy = dec[7:15]
		} else {
			ownerSalt = dec[7:15]
			ownerEntropy = ownerSalt
		}

		prefactorA, err := scrypt.Key([]byte(passphrase), ownerSalt, 16384, 8, 8, 32)
		if prefactorA == nil {
			log.Fatal(err)
		}

		var passFactor []byte
		if hasLotSequence {
			prefactorB := bytes.Join([][]byte{prefactorA, ownerEntropy}, nil)
			passFactor = sha256Twice(prefactorB)
		} else {
			passFactor = prefactorA
		}

		passpoint := btc.PublicFromPrivate(passFactor, true)
		if passpoint == nil {
			log.Fatal(err)
		}

		encryptedpart1 := dec[15:23]
		encryptedpart2 := dec[23:39]

		derived, err := scrypt.Key(passpoint, bytes.Join([][]byte{dec[3:7], ownerEntropy}, nil), 1024, 1, 1, 64)
		if derived == nil {
			log.Fatal(err)
		}

		h, err := aes.NewCipher(derived[32:])
		if h == nil {
			log.Fatal(err)
		}

		unencryptedpart2 := make([]byte, 16)
		h.Decrypt(unencryptedpart2, encryptedpart2)
		for i := range unencryptedpart2 {
			unencryptedpart2[i] ^= derived[i+16]
		}

		encryptedpart1 = bytes.Join([][]byte{encryptedpart1, unencryptedpart2[:8]}, nil)

		unencryptedpart1 := make([]byte, 16)
		h.Decrypt(unencryptedpart1, encryptedpart1)
		for i := range unencryptedpart1 {
			unencryptedpart1[i] ^= derived[i]
		}

		seeddb := bytes.Join([][]byte{unencryptedpart1[:16], unencryptedpart2[8:]}, nil)
		factorb := sha256Twice(seeddb)

		bigN, success := new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16)
		if !success {
			log.Fatal("Failed to create Int for N")
		}

		passFactorBig := new(big.Int).SetBytes(passFactor)
		factorbBig := new(big.Int).SetBytes(factorb)

		privKey := new(big.Int)
		privKey.Mul(passFactorBig, factorbBig)
		privKey.Mod(privKey, bigN)

		pubKey := btc.PublicFromPrivate(privKey.Bytes(), compress)
		if pubKey == nil {
			log.Fatal(err)
		}

		addr := btc.NewAddrFromPubkey(pubKey, 0).String()

		addrHashed := sha256Twice([]byte(addr))

		if addrHashed[0] != dec[3] || addrHashed[1] != dec[4] || addrHashed[2] != dec[5] || addrHashed[3] != dec[6] {
			return ""
		}

		return hex.EncodeToString(privKey.Bytes())
	}

	log.Fatal("Malformed byte slice")
	return ""
}
<|endoftext|>


<commit_before>// Copyright 2018 The Ebiten 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.

// +build example jsgo

package main

import (
	"fmt"
	_ "image/jpeg"
	"log"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
)

var (
	count          int
	highDPIImage   *ebiten.Image
	highDPIImageCh = make(chan *ebiten.Image)

	// scale represents the device scale when the application starts.
	scale = 1.0
)

func init() {
	// Licensed under Public Domain
	// https://commons.wikimedia.org/wiki/File:As08-16-2593.jpg
	const url = "https://upload.wikimedia.org/wikipedia/commons/1/1f/As08-16-2593.jpg"

	// Load the image asynchronously.
	go func() {
		img, err := ebitenutil.NewImageFromURL(url)
		if err != nil {
			log.Fatal(err)
		}
		highDPIImageCh <- img
		close(highDPIImageCh)
	}()
}

func update(screen *ebiten.Image) error {
	// TODO: DeviceScaleFactor() might return different values for different monitors.
	// Add a mode to adjust the screen size along with the current device scale (#705).
	// Now this example uses the device scale initialized at the beginning of this application.

	if highDPIImage == nil {
		// Use select and 'default' clause for non-blocking receiving.
		select {
		case img := <-highDPIImageCh:
			highDPIImage = img
		default:
		}
	}

	if ebiten.IsDrawingSkipped() {
		return nil
	}

	if highDPIImage == nil {
		ebitenutil.DebugPrint(screen, "Loading the image...")
		return nil
	}

	sw, sh := screen.Size()

	w, h := highDPIImage.Size()
	op := &ebiten.DrawImageOptions{}

	// Move the images's center to the upper left corner.
	op.GeoM.Translate(float64(-w)/2, float64(-h)/2)

	// The image is just too big. Adjust the scale.
	op.GeoM.Scale(0.25, 0.25)

	// Scale the image by the device ratio so that the rendering result can be same
	// on various (different-DPI) environments.
	op.GeoM.Scale(scale, scale)

	// Move the image's center to the screen's center.
	op.GeoM.Translate(float64(sw)/2, float64(sh)/2)

	op.Filter = ebiten.FilterLinear
	screen.DrawImage(highDPIImage, op)

	ebitenutil.DebugPrint(screen, fmt.Sprintf("(Init) Device Scale Ratio: %0.2f", scale))
	return nil
}

func main() {
	const (
		screenWidth  = 640
		screenHeight = 480
	)

	// Pass the invert of scale so that Ebiten's auto scaling by device scale is disabled.
	//
	// Note that DeviceScaleFactor cannot be called from init() functions on some environments.
	scale = ebiten.DeviceScaleFactor()
	s := scale
	if err := ebiten.Run(update, int(screenWidth*s), int(screenHeight*s), 1/s, "High DPI (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>examples/highdpi: Use RunGame<commit_after>// Copyright 2018 The Ebiten 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.

// +build example jsgo

package main

import (
	"fmt"
	_ "image/jpeg"
	"log"

	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/ebitenutil"
)

var (
	highDPIImageCh = make(chan *ebiten.Image)
)

func init() {
	// Licensed under Public Domain
	// https://commons.wikimedia.org/wiki/File:As08-16-2593.jpg
	const url = "https://upload.wikimedia.org/wikipedia/commons/1/1f/As08-16-2593.jpg"

	// Load the image asynchronously.
	go func() {
		img, err := ebitenutil.NewImageFromURL(url)
		if err != nil {
			log.Fatal(err)
		}
		highDPIImageCh <- img
		close(highDPIImageCh)
	}()
}

type Game struct {
	highDPIImage *ebiten.Image
}

func (g *Game) Update(screen *ebiten.Image) error {
	// TODO: DeviceScaleFactor() might return different values for different monitors.
	// Add a mode to adjust the screen size along with the current device scale (#705).
	// Now this example uses the device scale initialized at the beginning of this application.

	if g.highDPIImage != nil {
		return nil
	}

	// Use select and 'default' clause for non-blocking receiving.
	select {
	case img := <-highDPIImageCh:
		g.highDPIImage = img
	default:
	}

	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	if g.highDPIImage == nil {
		ebitenutil.DebugPrint(screen, "Loading the image...")
		return
	}

	sw, sh := screen.Size()

	w, h := g.highDPIImage.Size()
	op := &ebiten.DrawImageOptions{}

	// Move the images's center to the upper left corner.
	op.GeoM.Translate(float64(-w)/2, float64(-h)/2)

	// The image is just too big. Adjust the scale.
	op.GeoM.Scale(0.25, 0.25)

	// Scale the image by the device ratio so that the rendering result can be same
	// on various (different-DPI) environments.
	scale := ebiten.DeviceScaleFactor()
	op.GeoM.Scale(scale, scale)

	// Move the image's center to the screen's center.
	op.GeoM.Translate(float64(sw)/2, float64(sh)/2)

	op.Filter = ebiten.FilterLinear
	screen.DrawImage(g.highDPIImage, op)

	ebitenutil.DebugPrint(screen, fmt.Sprintf("(Init) Device Scale Ratio: %0.2f", scale))
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	// The unit of outsideWidth/Height is device-independent pixels.
	// By multiplying them by the device scale factor, we can get a hi-DPI screen size.
	s := ebiten.DeviceScaleFactor()
	return int(float64(outsideWidth) * s), int(float64(outsideHeight) * s)
}

func main() {
	ebiten.SetWindowSize(640, 480)
	ebiten.SetWindowTitle("High DPI (Ebiten Demo)")
	if err := ebiten.RunGame(&Game{}); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package core

import (
	"fmt"

	"github.com/af83/edwig/audit"
	"github.com/af83/edwig/logger"
	"github.com/af83/edwig/model"
	"github.com/af83/edwig/siri"
)

type SubscriptionRequestDispatcher interface {
	Dispatch(*siri.XMLSubscriptionRequest) (*siri.SIRISubscriptionResponse, error)
	CancelSubscription(*siri.XMLDeleteSubscriptionRequest) *siri.SIRIDeleteSubscriptionResponse
}

type SIRISubscriptionRequestDispatcherFactory struct{}

type SIRISubscriptionRequestDispatcher struct {
	model.ClockConsumer
	model.UUIDConsumer

	siriConnector

	xmlRequest siri.XMLSubscriptionRequest
}

func (factory *SIRISubscriptionRequestDispatcherFactory) Validate(apiPartner *APIPartner) bool {
	ok := apiPartner.ValidatePresenceOfSetting("remote_objectid_kind")
	ok = ok && apiPartner.ValidatePresenceOfSetting("remote_url")
	ok = ok && apiPartner.ValidatePresenceOfSetting("remote_credential")
	return ok
}

func (factory *SIRISubscriptionRequestDispatcherFactory) CreateConnector(partner *Partner) Connector {
	return NewSIRISubscriptionRequestDispatcher(partner)
}

func NewSIRISubscriptionRequestDispatcher(partner *Partner) *SIRISubscriptionRequestDispatcher {
	siriSubscriptionRequest := &SIRISubscriptionRequestDispatcher{}
	siriSubscriptionRequest.partner = partner

	return siriSubscriptionRequest
}

func (connector *SIRISubscriptionRequestDispatcher) Dispatch(request *siri.XMLSubscriptionRequest) (*siri.SIRISubscriptionResponse, error) {
	logStashEvent := connector.newLogStashEvent()

	logXMLSubscriptionRequest(logStashEvent, request)

	response := siri.SIRISubscriptionResponse{
		Address:            connector.Partner().Address(),
		ResponderRef:       connector.SIRIPartner().RequestorRef(),
		ResponseTimestamp:  connector.Clock().Now(),
		RequestMessageRef:  request.MessageIdentifier(),
		ServiceStartedTime: connector.Partner().Referential().StartedAt(),
	}

	if len(request.XMLSubscriptionGMEntries()) > 0 {
		gmbc, ok := connector.Partner().Connector(SIRI_GENERAL_MESSAGE_SUBSCRIPTION_BROADCASTER)
		if !ok {
			return nil, fmt.Errorf("No GeneralMessageSubscriptionBroadcaster Connector")
		}
		for _, sgm := range gmbc.(*SIRIGeneralMessageSubscriptionBroadcaster).HandleSubscriptionRequest(request) {
			response.ResponseStatus = append(response.ResponseStatus, sgm)
		}
		logSIRISubscriptionResponse(logStashEvent, &response, "GeneralMessageSubscriptionBroadcaster")
		audit.CurrentLogStash().WriteEvent(logStashEvent)
		return &response, nil
	}

	if len(request.XMLSubscriptionSMEntries()) > 0 {
		smbc, ok := connector.Partner().Connector(SIRI_STOP_MONITORING_SUBSCRIPTION_BROADCASTER)
		if !ok {
			return nil, fmt.Errorf("No StopMonitoringSubscriptionBroadcaster Connector")
		}
		for _, smr := range smbc.(*SIRIStopMonitoringSubscriptionBroadcaster).HandleSubscriptionRequest(request) {
			response.ResponseStatus = append(response.ResponseStatus, smr)
		}
		logSIRISubscriptionResponse(logStashEvent, &response, "StopMonitoringSubscriptionBroadcaster")
		audit.CurrentLogStash().WriteEvent(logStashEvent)
		return &response, nil
	}

	if len(request.XMLSubscriptionETTEntries()) > 0 {
		smbc, ok := connector.Partner().Connector(SIRI_ESTIMATED_TIMETABLE_SUBSCRIPTION_BROADCASTER)
		if !ok {
			return nil, fmt.Errorf("No EstimatedTimeTableSubscriptionBroadcaster Connector")
		}
		for _, smr := range smbc.(*SIRIEstimatedTimeTableSubscriptionBroadcaster).HandleSubscriptionRequest(request) {
			response.ResponseStatus = append(response.ResponseStatus, smr)
		}
		logSIRISubscriptionResponse(logStashEvent, &response, "EstimatedTimeTableSubscriptionBroadcaster")
		audit.CurrentLogStash().WriteEvent(logStashEvent)
		return &response, nil
	}

	return nil, fmt.Errorf("Subscription not supported")
}

func (connector *SIRISubscriptionRequestDispatcher) CancelSubscription(r *siri.XMLDeleteSubscriptionRequest) *siri.SIRIDeleteSubscriptionResponse {
	logStashEvent := connector.newLogStashEvent()

	logXMLCancelSubscriptionRequest(logStashEvent, r)
	audit.CurrentLogStash().WriteEvent(logStashEvent)

	currentTime := connector.Clock().Now()
	resp := &siri.SIRIDeleteSubscriptionResponse{
		ResponderRef:      connector.SIRIPartner().RequestorRef(),
		RequestMessageRef: r.MessageIdentifier(),
		ResponseTimestamp: currentTime,
	}

	defer func() {
		logStashEvent := connector.newLogStashEvent()
		logSIRICancelSubscriptionResponse(logStashEvent, resp)
		audit.CurrentLogStash().WriteEvent(logStashEvent)
	}()

	if r.CancelAll() {
		for _, subscription := range connector.Partner().Subscriptions().FindBroadcastSubscriptions() {
			responseStatus := &siri.SIRITerminationResponseStatus{
				SubscriberRef:     r.RequestorRef(),
				SubscriptionRef:   subscription.ExternalId(),
				ResponseTimestamp: currentTime,
				Status:            true,
			}
			resp.ResponseStatus = append(resp.ResponseStatus, responseStatus)
		}
		connector.Partner().CancelBroadcastSubscriptions()
		return resp
	}

	responseStatus := &siri.SIRITerminationResponseStatus{
		SubscriberRef:     r.RequestorRef(),
		SubscriptionRef:   r.SubscriptionRef(),
		ResponseTimestamp: currentTime,
	}

	resp.ResponseStatus = append(resp.ResponseStatus, responseStatus)

	sub, ok := connector.Partner().Subscriptions().FindByExternalId(r.SubscriptionRef())
	if !ok {
		logger.Log.Debugf("Could not Unsubscribe to unknow subscription %v", r.SubscriptionRef())

		responseStatus.ErrorType = "InvalidDataReferencesError"
		responseStatus.ErrorText = fmt.Sprintf("Subscription not found: '%s'", r.SubscriptionRef())
		return resp
	}

	responseStatus.Status = true

	sub.Delete()
	return resp
}

func (connector *SIRISubscriptionRequestDispatcher) newLogStashEvent() audit.LogStashEvent {
	return connector.partner.NewLogStashEvent()
}

func logXMLSubscriptionRequest(logStashEvent audit.LogStashEvent, request *siri.XMLSubscriptionRequest) {
	logStashEvent["consumerAddress"] = request.ConsumerAddress()
	logStashEvent["messageIdentifier"] = request.MessageIdentifier()
	logStashEvent["requestorRef"] = request.RequestorRef()
	logStashEvent["requestTimestamp"] = request.RequestTimestamp().String()
	logStashEvent["requestXML"] = request.RawXML()
}

func logSIRISubscriptionResponse(logStashEvent audit.LogStashEvent, response *siri.SIRISubscriptionResponse, connector string) {
	logStashEvent["connector"] = connector
	logStashEvent["type"] = "subscriptionResponse"
	logStashEvent["address"] = response.Address
	logStashEvent["responderRef"] = response.ResponderRef
	logStashEvent["requestMessageRef"] = response.RequestMessageRef
	logStashEvent["responseTimestamp"] = response.ResponseTimestamp.String()
	logStashEvent["serviceStartedTime"] = response.ServiceStartedTime.String()
	xml, err := response.BuildXML()
	if err != nil {
		logStashEvent["responseXML"] = fmt.Sprintf("%v", err)
		return
	}
	logStashEvent["responseXML"] = xml
}

func logXMLCancelSubscriptionRequest(logStashEvent audit.LogStashEvent, request *siri.XMLDeleteSubscriptionRequest) {
	logStashEvent["type"] = "DeleteSubscription"
	logStashEvent["messageIdentifier"] = request.MessageIdentifier()
	logStashEvent["requestorRef"] = request.RequestorRef()
	logStashEvent["requestTimestamp"] = request.RequestTimestamp().String()
	if request.CancelAll() {
		logStashEvent["subscriptionToCancel"] = "All"
	} else {
		logStashEvent["subscriptionToCancel"] = request.SubscriptionRef()
	}
	logStashEvent["requestXML"] = request.RawXML()
}

func logSIRICancelSubscriptionResponse(logStashEvent audit.LogStashEvent, response *siri.SIRIDeleteSubscriptionResponse) {
	logStashEvent["responderRef"] = response.ResponderRef
	logStashEvent["requestMessageRef"] = response.RequestMessageRef
	logStashEvent["responseTimestamp"] = response.ResponseTimestamp.String()
	xml, err := response.BuildXML()
	if err != nil {
		logStashEvent["responseXML"] = fmt.Sprintf("%v", err)
		return
	}
	logStashEvent["responseXML"] = xml
}
<commit_msg>log fix<commit_after>package core

import (
	"fmt"

	"github.com/af83/edwig/audit"
	"github.com/af83/edwig/logger"
	"github.com/af83/edwig/model"
	"github.com/af83/edwig/siri"
)

type SubscriptionRequestDispatcher interface {
	Dispatch(*siri.XMLSubscriptionRequest) (*siri.SIRISubscriptionResponse, error)
	CancelSubscription(*siri.XMLDeleteSubscriptionRequest) *siri.SIRIDeleteSubscriptionResponse
}

type SIRISubscriptionRequestDispatcherFactory struct{}

type SIRISubscriptionRequestDispatcher struct {
	model.ClockConsumer
	model.UUIDConsumer

	siriConnector

	xmlRequest siri.XMLSubscriptionRequest
}

func (factory *SIRISubscriptionRequestDispatcherFactory) Validate(apiPartner *APIPartner) bool {
	ok := apiPartner.ValidatePresenceOfSetting("remote_objectid_kind")
	ok = ok && apiPartner.ValidatePresenceOfSetting("remote_url")
	ok = ok && apiPartner.ValidatePresenceOfSetting("remote_credential")
	return ok
}

func (factory *SIRISubscriptionRequestDispatcherFactory) CreateConnector(partner *Partner) Connector {
	return NewSIRISubscriptionRequestDispatcher(partner)
}

func NewSIRISubscriptionRequestDispatcher(partner *Partner) *SIRISubscriptionRequestDispatcher {
	siriSubscriptionRequest := &SIRISubscriptionRequestDispatcher{}
	siriSubscriptionRequest.partner = partner

	return siriSubscriptionRequest
}

func (connector *SIRISubscriptionRequestDispatcher) Dispatch(request *siri.XMLSubscriptionRequest) (*siri.SIRISubscriptionResponse, error) {
	logStashEvent := connector.newLogStashEvent()

	logXMLSubscriptionRequest(logStashEvent, request)
	audit.CurrentLogStash().WriteEvent(logStashEvent)

	response := siri.SIRISubscriptionResponse{
		Address:            connector.Partner().Address(),
		ResponderRef:       connector.SIRIPartner().RequestorRef(),
		ResponseTimestamp:  connector.Clock().Now(),
		RequestMessageRef:  request.MessageIdentifier(),
		ServiceStartedTime: connector.Partner().Referential().StartedAt(),
	}

	if len(request.XMLSubscriptionGMEntries()) > 0 {
		logStashEvent := connector.newLogStashEvent()

		gmbc, ok := connector.Partner().Connector(SIRI_GENERAL_MESSAGE_SUBSCRIPTION_BROADCASTER)
		if !ok {
			return nil, fmt.Errorf("No GeneralMessageSubscriptionBroadcaster Connector")
		}
		for _, sgm := range gmbc.(*SIRIGeneralMessageSubscriptionBroadcaster).HandleSubscriptionRequest(request) {
			response.ResponseStatus = append(response.ResponseStatus, sgm)
		}
		logSIRISubscriptionResponse(logStashEvent, &response, "GeneralMessageSubscriptionBroadcaster")
		audit.CurrentLogStash().WriteEvent(logStashEvent)
		return &response, nil
	}

	if len(request.XMLSubscriptionSMEntries()) > 0 {
		logStashEvent := connector.newLogStashEvent()

		smbc, ok := connector.Partner().Connector(SIRI_STOP_MONITORING_SUBSCRIPTION_BROADCASTER)
		if !ok {
			return nil, fmt.Errorf("No StopMonitoringSubscriptionBroadcaster Connector")
		}
		for _, smr := range smbc.(*SIRIStopMonitoringSubscriptionBroadcaster).HandleSubscriptionRequest(request) {
			response.ResponseStatus = append(response.ResponseStatus, smr)
		}
		logSIRISubscriptionResponse(logStashEvent, &response, "StopMonitoringSubscriptionBroadcaster")
		audit.CurrentLogStash().WriteEvent(logStashEvent)
		return &response, nil
	}

	if len(request.XMLSubscriptionETTEntries()) > 0 {
		logStashEvent := connector.newLogStashEvent()

		smbc, ok := connector.Partner().Connector(SIRI_ESTIMATED_TIMETABLE_SUBSCRIPTION_BROADCASTER)
		if !ok {
			return nil, fmt.Errorf("No EstimatedTimeTableSubscriptionBroadcaster Connector")
		}
		for _, smr := range smbc.(*SIRIEstimatedTimeTableSubscriptionBroadcaster).HandleSubscriptionRequest(request) {
			response.ResponseStatus = append(response.ResponseStatus, smr)
		}
		logSIRISubscriptionResponse(logStashEvent, &response, "EstimatedTimeTableSubscriptionBroadcaster")
		audit.CurrentLogStash().WriteEvent(logStashEvent)
		return &response, nil
	}

	return nil, fmt.Errorf("Subscription not supported")
}

func (connector *SIRISubscriptionRequestDispatcher) CancelSubscription(r *siri.XMLDeleteSubscriptionRequest) *siri.SIRIDeleteSubscriptionResponse {
	logStashEvent := connector.newLogStashEvent()

	logXMLCancelSubscriptionRequest(logStashEvent, r)
	audit.CurrentLogStash().WriteEvent(logStashEvent)

	currentTime := connector.Clock().Now()
	resp := &siri.SIRIDeleteSubscriptionResponse{
		ResponderRef:      connector.SIRIPartner().RequestorRef(),
		RequestMessageRef: r.MessageIdentifier(),
		ResponseTimestamp: currentTime,
	}

	defer func() {
		logStashEvent := connector.newLogStashEvent()
		logSIRICancelSubscriptionResponse(logStashEvent, resp)
		audit.CurrentLogStash().WriteEvent(logStashEvent)
	}()

	if r.CancelAll() {
		for _, subscription := range connector.Partner().Subscriptions().FindBroadcastSubscriptions() {
			responseStatus := &siri.SIRITerminationResponseStatus{
				SubscriberRef:     r.RequestorRef(),
				SubscriptionRef:   subscription.ExternalId(),
				ResponseTimestamp: currentTime,
				Status:            true,
			}
			resp.ResponseStatus = append(resp.ResponseStatus, responseStatus)
		}
		connector.Partner().CancelBroadcastSubscriptions()
		return resp
	}

	responseStatus := &siri.SIRITerminationResponseStatus{
		SubscriberRef:     r.RequestorRef(),
		SubscriptionRef:   r.SubscriptionRef(),
		ResponseTimestamp: currentTime,
	}

	resp.ResponseStatus = append(resp.ResponseStatus, responseStatus)

	sub, ok := connector.Partner().Subscriptions().FindByExternalId(r.SubscriptionRef())
	if !ok {
		logger.Log.Debugf("Could not Unsubscribe to unknow subscription %v", r.SubscriptionRef())

		responseStatus.ErrorType = "InvalidDataReferencesError"
		responseStatus.ErrorText = fmt.Sprintf("Subscription not found: '%s'", r.SubscriptionRef())
		return resp
	}

	responseStatus.Status = true

	sub.Delete()
	return resp
}

func (connector *SIRISubscriptionRequestDispatcher) newLogStashEvent() audit.LogStashEvent {
	return connector.partner.NewLogStashEvent()
}

func logXMLSubscriptionRequest(logStashEvent audit.LogStashEvent, request *siri.XMLSubscriptionRequest) {
	logStashEvent["consumerAddress"] = request.ConsumerAddress()
	logStashEvent["messageIdentifier"] = request.MessageIdentifier()
	logStashEvent["requestorRef"] = request.RequestorRef()
	logStashEvent["requestTimestamp"] = request.RequestTimestamp().String()
	logStashEvent["requestXML"] = request.RawXML()
}

func logSIRISubscriptionResponse(logStashEvent audit.LogStashEvent, response *siri.SIRISubscriptionResponse, connector string) {
	logStashEvent["connector"] = connector
	logStashEvent["type"] = "subscriptionResponse"
	logStashEvent["address"] = response.Address
	logStashEvent["responderRef"] = response.ResponderRef
	logStashEvent["requestMessageRef"] = response.RequestMessageRef
	logStashEvent["responseTimestamp"] = response.ResponseTimestamp.String()
	logStashEvent["serviceStartedTime"] = response.ServiceStartedTime.String()
	xml, err := response.BuildXML()
	if err != nil {
		logStashEvent["responseXML"] = fmt.Sprintf("%v", err)
		return
	}
	logStashEvent["responseXML"] = xml
}

func logXMLCancelSubscriptionRequest(logStashEvent audit.LogStashEvent, request *siri.XMLDeleteSubscriptionRequest) {
	logStashEvent["type"] = "DeleteSubscription"
	logStashEvent["messageIdentifier"] = request.MessageIdentifier()
	logStashEvent["requestorRef"] = request.RequestorRef()
	logStashEvent["requestTimestamp"] = request.RequestTimestamp().String()
	if request.CancelAll() {
		logStashEvent["subscriptionToCancel"] = "All"
	} else {
		logStashEvent["subscriptionToCancel"] = request.SubscriptionRef()
	}
	logStashEvent["requestXML"] = request.RawXML()
}

func logSIRICancelSubscriptionResponse(logStashEvent audit.LogStashEvent, response *siri.SIRIDeleteSubscriptionResponse) {
	logStashEvent["responderRef"] = response.ResponderRef
	logStashEvent["requestMessageRef"] = response.RequestMessageRef
	logStashEvent["responseTimestamp"] = response.ResponseTimestamp.String()
	xml, err := response.BuildXML()
	if err != nil {
		logStashEvent["responseXML"] = fmt.Sprintf("%v", err)
		return
	}
	logStashEvent["responseXML"] = xml
}
<|endoftext|>


<commit_before>package frame

import (
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"

	"github.com/zetamatta/nyagos/dos"
	"github.com/zetamatta/nyagos/shell"
)

var OptionNorc = false
var OptionGoColorable = true
var OptionEnableVirtualTerminalProcessing = false

type ScriptEngineForOption interface {
	SetArg([]string)
	RunFile(context.Context, string) ([]byte, error)
	RunString(context.Context, string) error
}

func OptionParse(sh *shell.Shell, e ScriptEngineForOption) (func(context.Context) error, error) {
	args := os.Args[1:]
	for i := 0; i < len(args); i++ {
		arg1 := args[i]
		if arg1 == "-k" {
			i++
			if i >= len(args) {
				return nil, errors.New("-k: requires parameters")
			}
			return func(ctx context.Context) error {
				sh.Interpret(ctx, args[i])
				return nil
			}, nil
		} else if arg1 == "-c" {
			i++
			if i >= len(args) {
				return nil, errors.New("-c: requires parameters")
			}
			return func(ctx context.Context) error {
				sh.Interpret(ctx, args[i])
				return io.EOF
			}, nil
		} else if arg1 == "-b" {
			i++
			if i >= len(args) {
				return nil, errors.New("-b: requires parameters")
			}
			data, err := base64.StdEncoding.DecodeString(args[i])
			if err != nil {
				return nil, err
			}
			text := string(data)
			return func(ctx context.Context) error {
				sh.Interpret(ctx, text)
				return io.EOF
			}, nil
		} else if arg1 == "-f" {
			i++
			if i >= len(args) {
				return nil, errors.New("-f: requires parameters")
			}
			if strings.HasSuffix(strings.ToLower(args[i]), ".lua") {
				// lua script
				return func(ctx context.Context) error {
					e.SetArg(args[i:])
					_, err := e.RunFile(ctx, args[i])
					if err != nil {
						return err
					} else {
						return io.EOF
					}
				}, nil
			} else {
				return func(ctx context.Context) error {
					// command script
					if err := sh.Source(ctx, args[i]); err != nil {
						return err
					}
					return io.EOF
				}, nil
			}
		} else if arg1 == "-e" {
			i++
			if i >= len(args) {
				return nil, errors.New("-e: requires parameters")
			}
			return func(ctx context.Context) error {
				e.SetArg(args[i:])
				err := e.RunString(ctx, args[i])
				if err != nil {
					return err
				} else {
					return io.EOF
				}
			}, nil
		} else if arg1 == "--norc" {
			OptionNorc = true
		} else if arg1 == "--lua-file" {
			i++
			if i >= len(args) {
				return nil, errors.New("--lua-file: requires parameters")
			}
			return func(ctx context.Context) error {
				e.SetArg(args[i:])
				_, err := e.RunFile(ctx, args[i])
				if err != nil {
					return err
				} else {
					return io.EOF
				}
			}, nil
		} else if arg1 == "--show-version-only" {
			return func(context.Context) error {
				fmt.Printf("%s-%s\n", Version, runtime.GOARCH)
				return io.EOF
			}, nil
		} else if arg1 == "--go-colorable" {
			OptionGoColorable = true
		} else if arg1 == "--no-go-colorable" {
			OptionGoColorable = false
		} else if arg1 == "--enable-virtual-terminal-processing" {
			OptionEnableVirtualTerminalProcessing = true
		} else if arg1 == "--disable-virtual-terminal-processing" {
			OptionEnableVirtualTerminalProcessing = false
		} else if arg1 == "--look-curdir-first" {
			shell.LookCurdirOrder = dos.LookCurdirFirst
		} else if arg1 == "--look-curdir-last" {
			shell.LookCurdirOrder = dos.LookCurdirLast
		} else if arg1 == "--look-curdir-never" {
			shell.LookCurdirOrder = dos.LookCurdirNever
		} else {
			fmt.Fprintf(os.Stderr, "%s: unknwon parameter\n", arg1)
		}
	}

	return nil, nil
}

var SilentMode = false
<commit_msg>option --show-version-only enables --norc automatically<commit_after>package frame

import (
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"io"
	"os"
	"runtime"
	"strings"

	"github.com/zetamatta/nyagos/dos"
	"github.com/zetamatta/nyagos/shell"
)

var OptionNorc = false
var OptionGoColorable = true
var OptionEnableVirtualTerminalProcessing = false

type ScriptEngineForOption interface {
	SetArg([]string)
	RunFile(context.Context, string) ([]byte, error)
	RunString(context.Context, string) error
}

func OptionParse(sh *shell.Shell, e ScriptEngineForOption) (func(context.Context) error, error) {
	args := os.Args[1:]
	for i := 0; i < len(args); i++ {
		arg1 := args[i]
		if arg1 == "-k" {
			i++
			if i >= len(args) {
				return nil, errors.New("-k: requires parameters")
			}
			return func(ctx context.Context) error {
				sh.Interpret(ctx, args[i])
				return nil
			}, nil
		} else if arg1 == "-c" {
			i++
			if i >= len(args) {
				return nil, errors.New("-c: requires parameters")
			}
			return func(ctx context.Context) error {
				sh.Interpret(ctx, args[i])
				return io.EOF
			}, nil
		} else if arg1 == "-b" {
			i++
			if i >= len(args) {
				return nil, errors.New("-b: requires parameters")
			}
			data, err := base64.StdEncoding.DecodeString(args[i])
			if err != nil {
				return nil, err
			}
			text := string(data)
			return func(ctx context.Context) error {
				sh.Interpret(ctx, text)
				return io.EOF
			}, nil
		} else if arg1 == "-f" {
			i++
			if i >= len(args) {
				return nil, errors.New("-f: requires parameters")
			}
			if strings.HasSuffix(strings.ToLower(args[i]), ".lua") {
				// lua script
				return func(ctx context.Context) error {
					e.SetArg(args[i:])
					_, err := e.RunFile(ctx, args[i])
					if err != nil {
						return err
					} else {
						return io.EOF
					}
				}, nil
			} else {
				return func(ctx context.Context) error {
					// command script
					if err := sh.Source(ctx, args[i]); err != nil {
						return err
					}
					return io.EOF
				}, nil
			}
		} else if arg1 == "-e" {
			i++
			if i >= len(args) {
				return nil, errors.New("-e: requires parameters")
			}
			return func(ctx context.Context) error {
				e.SetArg(args[i:])
				err := e.RunString(ctx, args[i])
				if err != nil {
					return err
				} else {
					return io.EOF
				}
			}, nil
		} else if arg1 == "--norc" {
			OptionNorc = true
		} else if arg1 == "--lua-file" {
			i++
			if i >= len(args) {
				return nil, errors.New("--lua-file: requires parameters")
			}
			return func(ctx context.Context) error {
				e.SetArg(args[i:])
				_, err := e.RunFile(ctx, args[i])
				if err != nil {
					return err
				} else {
					return io.EOF
				}
			}, nil
		} else if arg1 == "--show-version-only" {
			OptionNorc = true
			return func(context.Context) error {
				fmt.Printf("%s-%s\n", Version, runtime.GOARCH)
				return io.EOF
			}, nil
		} else if arg1 == "--go-colorable" {
			OptionGoColorable = true
		} else if arg1 == "--no-go-colorable" {
			OptionGoColorable = false
		} else if arg1 == "--enable-virtual-terminal-processing" {
			OptionEnableVirtualTerminalProcessing = true
		} else if arg1 == "--disable-virtual-terminal-processing" {
			OptionEnableVirtualTerminalProcessing = false
		} else if arg1 == "--look-curdir-first" {
			shell.LookCurdirOrder = dos.LookCurdirFirst
		} else if arg1 == "--look-curdir-last" {
			shell.LookCurdirOrder = dos.LookCurdirLast
		} else if arg1 == "--look-curdir-never" {
			shell.LookCurdirOrder = dos.LookCurdirNever
		} else {
			fmt.Fprintf(os.Stderr, "%s: unknwon parameter\n", arg1)
		}
	}

	return nil, nil
}

var SilentMode = false
<|endoftext|>


<commit_before>package content

import (
	"bytes"
	"compress/gzip"
	"encoding/json"
	"io"
	"io/ioutil"
	"net/url"

	"github.com/Masterminds/semver/v3"
	"github.com/rancher/rancher/pkg/api/steve/catalog/types"
	v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1"
	"github.com/rancher/rancher/pkg/catalogv2"
	"github.com/rancher/rancher/pkg/catalogv2/git"
	"github.com/rancher/rancher/pkg/catalogv2/helm"
	helmhttp "github.com/rancher/rancher/pkg/catalogv2/http"
	catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1"
	"github.com/rancher/rancher/pkg/settings"
	corecontrollers "github.com/rancher/wrangler/pkg/generated/controllers/core/v1"
	"github.com/rancher/wrangler/pkg/schemas/validation"
	"github.com/sirupsen/logrus"
	"helm.sh/helm/v3/pkg/repo"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Manager struct {
	configMaps   corecontrollers.ConfigMapCache
	secrets      corecontrollers.SecretCache
	clusterRepos catalogcontrollers.ClusterRepoCache
}

func NewManager(
	configMaps corecontrollers.ConfigMapCache,
	secrets corecontrollers.SecretCache,
	clusterRepos catalogcontrollers.ClusterRepoCache) *Manager {
	return &Manager{
		configMaps:   configMaps,
		secrets:      secrets,
		clusterRepos: clusterRepos,
	}
}

type repoDef struct {
	typedata *metav1.TypeMeta
	metadata *metav1.ObjectMeta
	spec     *v1.RepoSpec
	status   *v1.RepoStatus
}

func (c *Manager) getRepo(namespace, name string) (repoDef, error) {
	if namespace == "" {
		cr, err := c.clusterRepos.Get(name)
		if err != nil {
			return repoDef{}, err
		}
		return repoDef{
			typedata: &cr.TypeMeta,
			metadata: &cr.ObjectMeta,
			spec:     &cr.Spec,
			status:   &cr.Status,
		}, nil
	}

	panic("namespace should never be empty")
}

func (c *Manager) Index(namespace, name string) (*repo.IndexFile, error) {
	r, err := c.getRepo(namespace, name)
	if err != nil {
		return nil, err
	}

	cm, err := c.configMaps.Get(r.status.IndexConfigMapNamespace, r.status.IndexConfigMapName)
	if err != nil {
		return nil, err
	}

	if len(cm.OwnerReferences) == 0 || cm.OwnerReferences[0].UID != r.metadata.UID {
		return nil, validation.Unauthorized
	}

	gz, err := gzip.NewReader(bytes.NewBuffer(cm.BinaryData["content"]))
	if err != nil {
		return nil, err
	}
	defer gz.Close()

	data, err := ioutil.ReadAll(gz)
	if err != nil {
		return nil, err
	}

	index := &repo.IndexFile{}
	if err := json.Unmarshal(data, index); err != nil {
		return nil, err
	}
	return c.filterReleases(index), nil
}

func (c *Manager) filterReleases(index *repo.IndexFile) *repo.IndexFile {
	index.SortEntries()
	if !settings.IsRelease() {
		return index
	}

	rancherVersion, err := semver.NewVersion(settings.ServerVersion.Get())
	if err != nil {
		logrus.Errorf("failed to parse server version %s: %v", settings.ServerVersion.Get(), err)
		return index
	}

	for rel, versions := range index.Entries {
		newVersions := make([]*repo.ChartVersion, 0, len(versions))
		for _, version := range versions {
			if constraintStr, ok := version.Annotations["catalog.cattle.io/rancher-version"]; ok {
				if constraint, err := semver.NewConstraint(constraintStr); err == nil {
					if !constraint.Check(rancherVersion) {
						continue
					}
				} else {
					logrus.Errorf("failed to parse constraint version %s: %v", settings.ServerVersion.Get(), err)
				}
			}
			newVersions = append(newVersions, version)
		}

		if len(newVersions) == 0 {
			delete(index.Entries, rel)
		} else {
			index.Entries[rel] = newVersions
		}
	}

	return index
}

func (c *Manager) Icon(namespace, name, chartName, version string) (io.ReadCloser, string, error) {
	index, err := c.Index(namespace, name)
	if err != nil {
		return nil, "", err
	}

	chart, err := index.Get(chartName, version)
	if err != nil {
		return nil, "", err
	}

	repo, err := c.getRepo(namespace, name)
	if err != nil {
		return nil, "", err
	}

	if !isHTTP(chart.Icon) && repo.status.Commit != "" {
		return git.Icon(namespace, name, repo.status.URL, chart)
	}

	secret, err := catalogv2.GetSecret(c.secrets, repo.spec, repo.metadata.Namespace)
	if err != nil {
		return nil, "", err
	}

	return helmhttp.Icon(secret, repo.status.URL, repo.spec.CABundle, repo.spec.InsecureSkipTLSverify, chart)
}

func isHTTP(iconURL string) bool {
	u, err := url.Parse(iconURL)
	return err == nil && (u.Scheme == "http" || u.Scheme == "https")
}

func (c *Manager) Chart(namespace, name, chartName, version string) (io.ReadCloser, error) {
	index, err := c.Index(namespace, name)
	if err != nil {
		return nil, err
	}

	chart, err := index.Get(chartName, version)
	if err != nil {
		return nil, err
	}

	repo, err := c.getRepo(namespace, name)
	if err != nil {
		return nil, err
	}

	if repo.status.Commit != "" {
		return git.Chart(namespace, name, repo.status.URL, chart)
	}

	secret, err := catalogv2.GetSecret(c.secrets, repo.spec, repo.metadata.Namespace)
	if err != nil {
		return nil, err
	}

	return helmhttp.Chart(secret, repo.status.URL, repo.spec.CABundle, repo.spec.InsecureSkipTLSverify, chart)
}

func (c *Manager) Info(namespace, name, chartName, version string) (*types.ChartInfo, error) {
	chart, err := c.Chart(namespace, name, chartName, version)
	if err != nil {
		return nil, err
	}
	defer chart.Close()

	return helm.InfoFromTarball(chart)
}
<commit_msg>Cache index repo file<commit_after>package content

import (
	"bytes"
	"compress/gzip"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/url"
	"sync"

	"github.com/Masterminds/semver/v3"
	"github.com/rancher/rancher/pkg/api/steve/catalog/types"
	v1 "github.com/rancher/rancher/pkg/apis/catalog.cattle.io/v1"
	"github.com/rancher/rancher/pkg/catalogv2"
	"github.com/rancher/rancher/pkg/catalogv2/git"
	"github.com/rancher/rancher/pkg/catalogv2/helm"
	helmhttp "github.com/rancher/rancher/pkg/catalogv2/http"
	catalogcontrollers "github.com/rancher/rancher/pkg/generated/controllers/catalog.cattle.io/v1"
	"github.com/rancher/rancher/pkg/settings"
	corecontrollers "github.com/rancher/wrangler/pkg/generated/controllers/core/v1"
	"github.com/rancher/wrangler/pkg/schemas/validation"
	"github.com/sirupsen/logrus"
	"helm.sh/helm/v3/pkg/repo"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type Manager struct {
	configMaps   corecontrollers.ConfigMapCache
	secrets      corecontrollers.SecretCache
	clusterRepos catalogcontrollers.ClusterRepoCache
	IndexCache   map[string]indexCache
	lock         sync.RWMutex
}

type indexCache struct {
	index    repo.IndexFile
	revision string
}

func NewManager(
	configMaps corecontrollers.ConfigMapCache,
	secrets corecontrollers.SecretCache,
	clusterRepos catalogcontrollers.ClusterRepoCache) *Manager {
	return &Manager{
		configMaps:   configMaps,
		secrets:      secrets,
		clusterRepos: clusterRepos,
		IndexCache:   map[string]indexCache{},
	}
}

type repoDef struct {
	typedata *metav1.TypeMeta
	metadata *metav1.ObjectMeta
	spec     *v1.RepoSpec
	status   *v1.RepoStatus
}

func (c *Manager) getRepo(namespace, name string) (repoDef, error) {
	if namespace == "" {
		cr, err := c.clusterRepos.Get(name)
		if err != nil {
			return repoDef{}, err
		}
		return repoDef{
			typedata: &cr.TypeMeta,
			metadata: &cr.ObjectMeta,
			spec:     &cr.Spec,
			status:   &cr.Status,
		}, nil
	}

	panic("namespace should never be empty")
}

func (c *Manager) Index(namespace, name string) (*repo.IndexFile, error) {
	r, err := c.getRepo(namespace, name)
	if err != nil {
		return nil, err
	}

	cm, err := c.configMaps.Get(r.status.IndexConfigMapNamespace, r.status.IndexConfigMapName)
	if err != nil {
		return nil, err
	}

	c.lock.RLock()
	if cache, ok := c.IndexCache[fmt.Sprintf("%s/%s", r.status.IndexConfigMapNamespace, r.status.IndexConfigMapName)]; ok {
		if cm.ResourceVersion == cache.revision {
			c.lock.RUnlock()
			return c.filterReleases(&cache.index), nil
		}
	}
	c.lock.RUnlock()

	if len(cm.OwnerReferences) == 0 || cm.OwnerReferences[0].UID != r.metadata.UID {
		return nil, validation.Unauthorized
	}

	gz, err := gzip.NewReader(bytes.NewBuffer(cm.BinaryData["content"]))
	if err != nil {
		return nil, err
	}
	defer gz.Close()

	data, err := ioutil.ReadAll(gz)
	if err != nil {
		return nil, err
	}

	index := &repo.IndexFile{}
	if err := json.Unmarshal(data, index); err != nil {
		return nil, err
	}

	c.lock.Lock()
	c.IndexCache[fmt.Sprintf("%s/%s", r.status.IndexConfigMapNamespace, r.status.IndexConfigMapName)] = indexCache{
		index:    *index,
		revision: cm.ResourceVersion,
	}
	c.lock.Unlock()

	return c.filterReleases(index), nil
}

func (c *Manager) filterReleases(index *repo.IndexFile) *repo.IndexFile {
	if !settings.IsRelease() {
		return index
	}

	rancherVersion, err := semver.NewVersion(settings.ServerVersion.Get())
	if err != nil {
		logrus.Errorf("failed to parse server version %s: %v", settings.ServerVersion.Get(), err)
		return index
	}

	for rel, versions := range index.Entries {
		newVersions := make([]*repo.ChartVersion, 0, len(versions))
		for _, version := range versions {
			if constraintStr, ok := version.Annotations["catalog.cattle.io/rancher-version"]; ok {
				if constraint, err := semver.NewConstraint(constraintStr); err == nil {
					if !constraint.Check(rancherVersion) {
						continue
					}
				} else {
					logrus.Errorf("failed to parse constraint version %s: %v", settings.ServerVersion.Get(), err)
				}
			}
			newVersions = append(newVersions, version)
		}

		if len(newVersions) == 0 {
			delete(index.Entries, rel)
		} else {
			index.Entries[rel] = newVersions
		}
	}

	return index
}

func (c *Manager) Icon(namespace, name, chartName, version string) (io.ReadCloser, string, error) {
	index, err := c.Index(namespace, name)
	if err != nil {
		return nil, "", err
	}

	chart, err := index.Get(chartName, version)
	if err != nil {
		return nil, "", err
	}

	repo, err := c.getRepo(namespace, name)
	if err != nil {
		return nil, "", err
	}

	if !isHTTP(chart.Icon) && repo.status.Commit != "" {
		return git.Icon(namespace, name, repo.status.URL, chart)
	}

	secret, err := catalogv2.GetSecret(c.secrets, repo.spec, repo.metadata.Namespace)
	if err != nil {
		return nil, "", err
	}

	return helmhttp.Icon(secret, repo.status.URL, repo.spec.CABundle, repo.spec.InsecureSkipTLSverify, chart)
}

func isHTTP(iconURL string) bool {
	u, err := url.Parse(iconURL)
	return err == nil && (u.Scheme == "http" || u.Scheme == "https")
}

func (c *Manager) Chart(namespace, name, chartName, version string) (io.ReadCloser, error) {
	index, err := c.Index(namespace, name)
	if err != nil {
		return nil, err
	}

	chart, err := index.Get(chartName, version)
	if err != nil {
		return nil, err
	}

	repo, err := c.getRepo(namespace, name)
	if err != nil {
		return nil, err
	}

	if repo.status.Commit != "" {
		return git.Chart(namespace, name, repo.status.URL, chart)
	}

	secret, err := catalogv2.GetSecret(c.secrets, repo.spec, repo.metadata.Namespace)
	if err != nil {
		return nil, err
	}

	return helmhttp.Chart(secret, repo.status.URL, repo.spec.CABundle, repo.spec.InsecureSkipTLSverify, chart)
}

func (c *Manager) Info(namespace, name, chartName, version string) (*types.ChartInfo, error) {
	chart, err := c.Chart(namespace, name, chartName, version)
	if err != nil {
		return nil, err
	}
	defer chart.Close()

	return helm.InfoFromTarball(chart)
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Christian Saide <Supernomad>
// Licensed under the MPL-2.0, for details see https://github.com/Supernomad/quantum/blob/master/LICENSE

package socket

import (
	"github.com/Supernomad/quantum/common"
)

// Type defines what kind of socket to use.
type Type int

const (
	// UDPSocket type creates and manages a UDP based socket.
	UDPSocket Type = iota

	// MOCKSocket type creates and manages a mocked out socket for testing.
	MOCKSocket
)

// Socket interface for a generic multi-queue socket interface.
type Socket interface {
	Read(buf []byte, queue int) (*common.Payload, bool)
	Write(payload *common.Payload, queue int) bool
	Open() error
	Close() error
	GetFDs() []int
}

// New generate a new Socket struct based on the supplied device socketType and user configuration.
func New(socketType Type, cfg *common.Config) Socket {
	switch socketType {
	case UDPSocket:
		return newUDP(cfg)
	case MOCKSocket:
		return newMock(cfg)
	}
	return nil
}
<commit_msg>Some more comments and docs<commit_after>// Copyright (c) 2016 Christian Saide <Supernomad>
// Licensed under the MPL-2.0, for details see https://github.com/Supernomad/quantum/blob/master/LICENSE

package socket

import (
	"github.com/Supernomad/quantum/common"
)

// Type defines what kind of socket to use.
type Type int

const (
	// UDPSocket type creates and manages a UDP based socket.
	UDPSocket Type = iota

	// MOCKSocket type creates and manages a mocked out socket for testing.
	MOCKSocket
)

// Socket interface for a generic multi-queue socket interface.
type Socket interface {
	// Read should return a formatted *common.Payload, based on the provided byte slice, off the specified socket queue.
	Read(buf []byte, queue int) (*common.Payload, bool)

	// Write should handle being passed a formatted *common.Payload, and write the underlying raw data to the specified socket queue.
	Write(payload *common.Payload, queue int) bool

	// Open should handle creating and configuring the socket.
	Open() error

	// Close should gracefully destroy the socket.
	Close() error

	// GetFDs should return all underlying queue file descriptors to pass along during a rolling restart.
	GetFDs() []int
}

// New generate a new Socket struct based on the supplied device socketType and user configuration.
func New(socketType Type, cfg *common.Config) Socket {
	switch socketType {
	case UDPSocket:
		return newUDP(cfg)
	case MOCKSocket:
		return newMock(cfg)
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import "github.com/vanng822/go-solr/solr"
import "fmt"

type TestResultParser struct {
	original_response map[string]interface{}
}

func (parser *TestResultParser) Parse(response *solr.SelectResponse) (*solr.SolrResult, error) {
	sr := &solr.SolrResult{}
	sr.Results = new(solr.Collection)
	sr.Status = response.Status

	if response.Status == 0 {
		parser.ParseResponse(response, sr)
		parser.ParseFacetCounts(response, sr)
		parser.ParseHighlighting(response, sr)
	} else {
		parser.ParseError(response, sr)
	}
	parser.original_response = response.Response

	return sr, nil
}

func (parser *TestResultParser) ParseError(response *solr.SelectResponse, sr *solr.SolrResult) {
	if error, ok := response.Response["error"]; ok {
		sr.Error = error.(map[string]interface{})
	}
}

func (parser *TestResultParser) ParseResponse(response *solr.SelectResponse, sr *solr.SolrResult) {
	if resp, ok := response.Response["response"].(map[string]interface{}); ok {
		sr.Results.NumFound = int(resp["numFound"].(float64))
		sr.Results.Start = int(resp["start"].(float64))
		if docs, ok := resp["docs"].([]interface{}); ok {
			sr.Results.Docs = make([]solr.Document, len(docs))
			// remove version
			for i, v := range docs {
				d := solr.Document{}
				for k, v := range v.(map[string]interface{}) {
					if k != "_version_" {
						d.Set(k, v)
					}
				}
				sr.Results.Docs[i] = d
			}
		}
	} else {
		panic(`Standard parser can only parse solr response with response object,
					ie response.response and response.response.docs.
					Please use other parser or implement your own parser`)
	}
}

func (parser *TestResultParser) ParseFacetCounts(response *solr.SelectResponse, sr *solr.SolrResult) {
	if facetCounts, ok := response.Response["facet_counts"]; ok {
		sr.Facet_counts = facetCounts.(map[string]interface{})
	}
}

func (parser *TestResultParser) ParseHighlighting(response *solr.SelectResponse, sr *solr.SolrResult) {
	if highlighting, ok := response.Response["highlighting"]; ok {
		sr.Highlighting = highlighting.(map[string]interface{})
	}
}

type InheritResultParser struct {
	solr.StandardResultParser
	original_response map[string]interface{}
}

func (parser *InheritResultParser) Parse(response *solr.SelectResponse) (*solr.SolrResult, error) {
	sr := &solr.SolrResult{}
	sr.Results = new(solr.Collection)
	sr.Status = response.Status

	if response.Status == 0 {
		parser.ParseResponse(response, sr)
	} else {
		parser.ParseError(response, sr)
	}
	parser.original_response = response.Response

	return sr, nil
}

func main() {
	si, _ := solr.NewSolrInterface("http://localhost:8983/solr/collection1")

	query := solr.NewQuery()
	query.AddParam("q", "title:add sucess 1")

	s := si.Search(query)

	parser := &TestResultParser{}
	r, err := s.Result(parser)
	_ = err

	fmt.Println(r.Results.Docs)
	fmt.Println(parser.original_response)

	parser2 := &InheritResultParser{}
	r2, err := s.Result(parser2)

	fmt.Println(r2.Results.Docs)

	fmt.Println(parser2.original_response)
}<commit_msg>Use new helper methods in example<commit_after>package main

import "github.com/vanng822/go-solr/solr"
import "fmt"

type TestResultParser struct {
	original_response map[string]interface{}
}

func (parser *TestResultParser) Parse(response *solr.SelectResponse) (*solr.SolrResult, error) {
	sr := &solr.SolrResult{}
	sr.Results = new(solr.Collection)
	sr.Status = response.Status

	if response.Status == 0 {
		parser.ParseResponse(response, sr)
		parser.ParseFacetCounts(response, sr)
		parser.ParseHighlighting(response, sr)
	} else {
		parser.ParseError(response, sr)
	}
	parser.original_response = response.Response

	return sr, nil
}

func (parser *TestResultParser) ParseError(response *solr.SelectResponse, sr *solr.SolrResult) {
	if error, ok := response.Response["error"]; ok {
		sr.Error = error.(map[string]interface{})
	}
}

func (parser *TestResultParser) ParseResponse(response *solr.SelectResponse, sr *solr.SolrResult) {
	if resp, ok := response.Response["response"].(map[string]interface{}); ok {
		sr.Results.NumFound = int(resp["numFound"].(float64))
		sr.Results.Start = int(resp["start"].(float64))
		if docs, ok := resp["docs"].([]interface{}); ok {
			sr.Results.Docs = make([]solr.Document, len(docs))
			// remove version
			for i, v := range docs {
				d := solr.Document{}
				for k, v := range v.(map[string]interface{}) {
					if k != "_version_" {
						d.Set(k, v)
					}
				}
				sr.Results.Docs[i] = d
			}
		}
	} else {
		panic(`Standard parser can only parse solr response with response object,
					ie response.response and response.response.docs.
					Please use other parser or implement your own parser`)
	}
}

func (parser *TestResultParser) ParseFacetCounts(response *solr.SelectResponse, sr *solr.SolrResult) {
	if facetCounts, ok := response.Response["facet_counts"]; ok {
		sr.Facet_counts = facetCounts.(map[string]interface{})
	}
}

func (parser *TestResultParser) ParseHighlighting(response *solr.SelectResponse, sr *solr.SolrResult) {
	if highlighting, ok := response.Response["highlighting"]; ok {
		sr.Highlighting = highlighting.(map[string]interface{})
	}
}

type InheritResultParser struct {
	solr.StandardResultParser
	original_response map[string]interface{}
}

func (parser *InheritResultParser) Parse(response *solr.SelectResponse) (*solr.SolrResult, error) {
	sr := &solr.SolrResult{}
	sr.Results = new(solr.Collection)
	sr.Status = response.Status

	if response.Status == 0 {
		parser.ParseResponse(response, sr)
	} else {
		parser.ParseError(response, sr)
	}
	parser.original_response = response.Response

	return sr, nil
}

func main() {
	si, _ := solr.NewSolrInterface("http://localhost:8983/solr/collection1")

	query := solr.NewQuery()
	query.Q("title:add sucess 1")
	query.Start(0)
	query.Rows(15)
	s := si.Search(query)

	parser := &TestResultParser{}
	r, err := s.Result(parser)
	_ = err

	fmt.Println(r.Results.Docs)
	fmt.Println(parser.original_response)

	parser2 := &InheritResultParser{}
	r2, err := s.Result(parser2)

	fmt.Println(r2.Results.Docs)

	fmt.Println(parser2.original_response)
}<|endoftext|>


<commit_before>// Copyright 2017 The Ebiten 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.

// +build example

package main

import (
	"bytes"
	"log"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/audio"
	"github.com/hajimehoshi/ebiten/v2/audio/wav"
	"github.com/hajimehoshi/ebiten/v2/ebitenutil"
	raudio "github.com/hajimehoshi/ebiten/v2/examples/resources/audio"
)

const (
	screenWidth  = 320
	screenHeight = 240
	sampleRate   = 44100
)

type Game struct {
	audioContext *audio.Context
	audioPlayer  *audio.Player
}

var g Game

func init() {
	var err error
	// Initialize audio context.
	g.audioContext = audio.NewContext(sampleRate)

	// In this example, embedded resource "Jab_wav" is used.
	//
	// If you want to use a wav file, open this and pass the file stream to wav.Decode.
	// Note that file's Close() should not be closed here
	// since audio.Player manages stream state.
	//
	//     f, err := os.Open("jab.wav")
	//     if err != nil {
	//         return err
	//     }
	//
	//     d, err := wav.Decode(g.audioContext, f)
	//     ...

	// Decode wav-formatted data and retrieve decoded PCM stream.
	d, err := wav.Decode(g.audioContext, bytes.NewReader(raudio.Jab_wav))
	if err != nil {
		log.Fatal(err)
	}

	// Create an audio.Player that has one stream.
	g.audioPlayer, err = audio.NewPlayer(g.audioContext, d)
	if err != nil {
		log.Fatal(err)
	}
}

func (g *Game) Update() error {
	if ebiten.IsKeyPressed(ebiten.KeyP) && !g.audioPlayer.IsPlaying() {
		// As audioPlayer has one stream and remembers the playing position,
		// rewinding is needed before playing when reusing audioPlayer.
		g.audioPlayer.Rewind()
		g.audioPlayer.Play()
	}
	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	if g.audioPlayer.IsPlaying() {
		ebitenutil.DebugPrint(screen, "Bump!")
	} else {
		ebitenutil.DebugPrint(screen, "Press P to play the wav")
	}
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	return screenWidth, screenHeight
}

func main() {
	ebiten.SetWindowSize(screenWidth*2, screenHeight*2)
	ebiten.SetWindowTitle("WAV (Ebiten Demo)")
	if err := ebiten.RunGame(&g); err != nil {
		log.Fatal(err)
	}
}
<commit_msg>examples/wav: Play SE immediately<commit_after>// Copyright 2017 The Ebiten 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.

// +build example

package main

import (
	"bytes"
	"log"

	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/audio"
	"github.com/hajimehoshi/ebiten/v2/audio/wav"
	"github.com/hajimehoshi/ebiten/v2/ebitenutil"
	raudio "github.com/hajimehoshi/ebiten/v2/examples/resources/audio"
	"github.com/hajimehoshi/ebiten/v2/inpututil"
)

const (
	screenWidth  = 320
	screenHeight = 240
	sampleRate   = 44100
)

type Game struct {
	audioContext *audio.Context
	audioPlayer  *audio.Player
}

var g Game

func init() {
	var err error
	// Initialize audio context.
	g.audioContext = audio.NewContext(sampleRate)

	// In this example, embedded resource "Jab_wav" is used.
	//
	// If you want to use a wav file, open this and pass the file stream to wav.Decode.
	// Note that file's Close() should not be closed here
	// since audio.Player manages stream state.
	//
	//     f, err := os.Open("jab.wav")
	//     if err != nil {
	//         return err
	//     }
	//
	//     d, err := wav.Decode(g.audioContext, f)
	//     ...

	// Decode wav-formatted data and retrieve decoded PCM stream.
	d, err := wav.Decode(g.audioContext, bytes.NewReader(raudio.Jab_wav))
	if err != nil {
		log.Fatal(err)
	}

	// Create an audio.Player that has one stream.
	g.audioPlayer, err = audio.NewPlayer(g.audioContext, d)
	if err != nil {
		log.Fatal(err)
	}
}

func (g *Game) Update() error {
	if inpututil.IsKeyJustPressed(ebiten.KeyP) {
		// As audioPlayer has one stream and remembers the playing position,
		// rewinding is needed before playing when reusing audioPlayer.
		g.audioPlayer.Rewind()
		g.audioPlayer.Play()
	}
	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	if g.audioPlayer.IsPlaying() {
		ebitenutil.DebugPrint(screen, "Bump!")
	} else {
		ebitenutil.DebugPrint(screen, "Press P to play the wav")
	}
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
	return screenWidth, screenHeight
}

func main() {
	ebiten.SetWindowSize(screenWidth*2, screenHeight*2)
	ebiten.SetWindowTitle("WAV (Ebiten Demo)")
	if err := ebiten.RunGame(&g); err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package drivers

import (
	"errors"
	"os"
	"path"

	"github.com/golang/glog"
)

// OnDiskStorageController is a way of testing the StorageController backend to ensure that all of the logic is correct.
type OnDiskStorageController struct {
	FSPath string
}

// NewOnDiskStorageController creates a new OnDiskStorageController
func NewOnDiskStorageController(path string) OnDiskStorageController {

	warning := `
********************************************************************************
*                                                                              *
*                                WARNING!!!                                    *
*             DO NOT USE the "On-Disk Controller" IN PRODUCTION!               *
*                                                                              *
*        You are currently using the On-Disk Storage Controller, it            *
*        operates on the host's disk with out the benifits of rdma and         *
*        should only be used for testing purposes. All data saved in           *
*        the volumes will still be available by manually accessing the         *
*        data in the host's filesystem.                                        *
*                                                                              *
********************************************************************************
	`

	glog.Warning(warning)

	if path == "" {
		path = "/etc/docker/mounts/"
	}

	glog.Info("Mount path: ", path)

	_, err := os.Open(path)
	if err != nil {
		os.MkdirAll(path, 0755)
		_, err = os.Open(path)
		if err != nil {
			glog.Fatal("Unable to create folder ", path, ". ", err)
		}
	}

	return OnDiskStorageController{path}
}

// Connect is a NOOP
func (d OnDiskStorageController) Connect() error {
	glog.Info("Connect function called, no action taken.")
	return nil
}

// Disconnect is a NOOP
func (d OnDiskStorageController) Disconnect() error {
	glog.Info("Disconnect function called, no action taken.")
	return nil
}

// Mount a particular volume
func (d OnDiskStorageController) Mount(volumeName string) (string, error) {
	pathMounted := path.Join(d.FSPath, volumeName)
	pathUnmounted := path.Join(path.Dir(pathMounted), path.Base(pathMounted)+".unmounted")

	// If there is an unmounted volume, return it.
	_, err := os.Open(pathUnmounted)
	if err == nil {
		glog.Info("Renaming: ", pathMounted, " to ", pathUnmounted)
		return pathMounted, os.Rename(pathUnmounted, pathMounted)
	}

	_, err = os.Open(pathMounted)
	if err != nil {
		glog.Info("Creating: ", pathMounted)
		os.MkdirAll(pathMounted, 0755)
		_, err = os.Open(pathMounted)
		if err != nil {
			return "", err
		}
	}

	return pathMounted, nil
}

// Unmount a particular volume
func (d OnDiskStorageController) Unmount(volumeName string) error {
	pathMounted := path.Join(d.FSPath, volumeName)
	pathUnmounted := path.Join(path.Dir(pathMounted), path.Base(pathMounted)+".unmounted")

	glog.Info(pathMounted)

	// If there is an unmounted volume, return it.
	_, err := os.Open(pathMounted)
	if err == nil {
		glog.Info("Renaming: ", pathMounted, " to ", pathUnmounted)
		return os.Rename(pathMounted, pathUnmounted)
	}

	_, err = os.Open(pathUnmounted)
	if err != nil {
		return err
	}

	return errors.New("already unmounted")
}

// Delete a particular volume
func (d OnDiskStorageController) Delete(volumeName string) error {
	pathMounted := path.Join(d.FSPath, volumeName)
	pathUnmounted := path.Join(path.Dir(pathMounted), path.Base(pathMounted)+".unmounted")

	// If there is an unmounted volume, return it.
	_, err := os.Open(pathUnmounted)
	if err == nil {
		return os.Remove(pathUnmounted)
	}

	_, err = os.Open(pathMounted)
	if err == nil {
		return os.Remove(pathMounted)
	}

	return nil
}
<commit_msg>Recursively remove volumes in ondisk<commit_after>package drivers

import (
	"errors"
	"os"
	"path"

	"github.com/golang/glog"
)

// OnDiskStorageController is a way of testing the StorageController backend to ensure that all of the logic is correct.
type OnDiskStorageController struct {
	FSPath string
}

// NewOnDiskStorageController creates a new OnDiskStorageController
func NewOnDiskStorageController(path string) OnDiskStorageController {

	warning := `
********************************************************************************
*                                                                              *
*                                WARNING!!!                                    *
*             DO NOT USE the "On-Disk Controller" IN PRODUCTION!               *
*                                                                              *
*        You are currently using the On-Disk Storage Controller, it            *
*        operates on the host's disk with out the benifits of rdma and         *
*        should only be used for testing purposes. All data saved in           *
*        the volumes will still be available by manually accessing the         *
*        data in the host's filesystem.                                        *
*                                                                              *
********************************************************************************
	`

	glog.Warning(warning)

	if path == "" {
		path = "/etc/docker/mounts/"
	}

	glog.Info("Mount path: ", path)

	_, err := os.Open(path)
	if err != nil {
		os.MkdirAll(path, 0755)
		_, err = os.Open(path)
		if err != nil {
			glog.Fatal("Unable to create folder ", path, ". ", err)
		}
	}

	return OnDiskStorageController{path}
}

// Connect is a NOOP
func (d OnDiskStorageController) Connect() error {
	glog.Info("Connect function called, no action taken.")
	return nil
}

// Disconnect is a NOOP
func (d OnDiskStorageController) Disconnect() error {
	glog.Info("Disconnect function called, no action taken.")
	return nil
}

// Mount a particular volume
func (d OnDiskStorageController) Mount(volumeName string) (string, error) {
	pathMounted := path.Join(d.FSPath, volumeName)
	pathUnmounted := path.Join(path.Dir(pathMounted), path.Base(pathMounted)+".unmounted")

	// If there is an unmounted volume, return it.
	_, err := os.Open(pathUnmounted)
	if err == nil {
		glog.Info("Renaming: ", pathMounted, " to ", pathUnmounted)
		return pathMounted, os.Rename(pathUnmounted, pathMounted)
	}

	_, err = os.Open(pathMounted)
	if err != nil {
		glog.Info("Creating: ", pathMounted)
		os.MkdirAll(pathMounted, 0755)
		_, err = os.Open(pathMounted)
		if err != nil {
			return "", err
		}
	}

	return pathMounted, nil
}

// Unmount a particular volume
func (d OnDiskStorageController) Unmount(volumeName string) error {
	pathMounted := path.Join(d.FSPath, volumeName)
	pathUnmounted := path.Join(path.Dir(pathMounted), path.Base(pathMounted)+".unmounted")

	glog.Info(pathMounted)

	// If there is an unmounted volume, return it.
	_, err := os.Open(pathMounted)
	if err == nil {
		glog.Info("Renaming: ", pathMounted, " to ", pathUnmounted)
		return os.Rename(pathMounted, pathUnmounted)
	}

	_, err = os.Open(pathUnmounted)
	if err != nil {
		return err
	}

	return errors.New("already unmounted")
}

// Delete a particular volume
func (d OnDiskStorageController) Delete(volumeName string) error {
	pathMounted := path.Join(d.FSPath, volumeName)
	pathUnmounted := path.Join(path.Dir(pathMounted), path.Base(pathMounted)+".unmounted")

	// If there is an unmounted volume, return it.
	_, err := os.Open(pathUnmounted)
	if err == nil {
		return os.RemoveAll(pathUnmounted)
	}

	_, err = os.Open(pathMounted)
	if err == nil {
		return os.RemoveAll(pathMounted)
	}

	return nil
}
<|endoftext|>