core

package
v1.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 20, 2020 License: MIT Imports: 50 Imported by: 0

Documentation

Overview

Package core provides different functions like error-reporting, logging, localization, etc. in order to make it easier to create transports. Usage:

package main

import (
    "os"
    "fmt"
    "html/template"

    "github.com/gin-gonic/gin"
    "github.com/gobuffalo/packr/v2"
    "github.com/retailcrm/mg-transport-core/core"
)

func main() {
    app := core.New()
    app.Config = core.NewConfig("config.yml")
    app.DefaultError = "unknown_error"
    app.TranslationsPath = "./translations"

    app.ConfigureRouter(func(engine *gin.Engine) {
        engine.Static("/static", "./static")
        engine.HTMLRender = app.CreateRenderer(
            func(renderer *core.Renderer) {
                // insert templates here. Example:
                r.Push("home", "templates/layout.html", "templates/home.html")
            },
            template.FuncMap{},
        )
    })

    if err := app.Prepare().Run(); err != nil {
        fmt.Printf("Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

Resource embedding

packr can be used to provide resource embedding, see:

https://github.com/gobuffalo/packr/tree/master/v2

In order to use packr you must follow instruction, and provide boxes with templates, translations and assets to library. You can find instruction here:

https://github.com/gobuffalo/packr/tree/master/v2#library-installation

Example of usage:

package main

import (
    "os"
    "fmt"
    "html/template"

    "github.com/gin-gonic/gin"
    "github.com/gobuffalo/packr/v2"
    "github.com/retailcrm/mg-transport-core/core"
)

func main() {
    static := packr.New("assets", "./static")
    templates := packr.New("templates", "./templates")
    translations := packr.New("translations", "./translate")

    app := core.New()
    app.Config = core.NewConfig("config.yml")
    app.DefaultError = "unknown_error"
    app.TranslationsBox = translations

    app.ConfigureRouter(func(engine *gin.Engine) {
        engine.StaticFS("/static", static)
        engine.HTMLRender = app.CreateRendererFS(
            templates,
            func(renderer *core.Renderer) {
                // insert templates here. Example:
                r.Push("home", "layout.html", "home.html")
            },
            template.FuncMap{},
        )
    })

    if err := app.Prepare().Run(); err != nil {
        fmt.Printf("Fatal error: %s", err.Error())
        os.Exit(1)
    }
}

Migration generator

This library contains helper tool for transports. You can install it via go:

$ go get -u github.com/retailcrm/mg-transport-core/cmd/transport-core-tool

Currently, it only can generate new migrations for your transport.

Index

Constants

View Source
const LocalizerContextKey = "localizer"

LocalizerContextKey is a key which is used to store localizer in gin.Context key-value storage

Variables

View Source
var DefaultCSRFTokenGetter = func(c *gin.Context) string {
	r := c.Request

	if t := r.URL.Query().Get("csrf_token"); len(t) > 0 {
		return t
	} else if t := r.Header.Get("X-CSRF-Token"); len(t) > 0 {
		return t
	} else if t := r.Header.Get("X-XSRF-Token"); len(t) > 0 {
		return t
	} else if c.Request.Body != nil {
		data, _ := ioutil.ReadAll(c.Request.Body)
		c.Request.Body = ioutil.NopCloser(bytes.NewReader(data))
		t := r.FormValue("csrf_token")
		c.Request.Body = ioutil.NopCloser(bytes.NewReader(data))

		if len(t) > 0 {
			return t
		}
	}

	return ""
}

DefaultCSRFTokenGetter default getter

View Source
var DefaultClient = http.DefaultClient

DefaultClient stores original http.DefaultClient

View Source
var DefaultIgnoredMethods = []string{"GET", "HEAD", "OPTIONS"}

DefaultIgnoredMethods ignored methods for CSRF verifier middleware

View Source
var DefaultLanguage = language.English

DefaultLanguage is a base language which will be chosen if current language is unspecified

DefaultLanguages for transports

View Source
var DefaultTransport = http.DefaultTransport

DefaultTransport stores original http.DefaultTransport

Functions

func BadRequest

func BadRequest(error string) (int, interface{})

BadRequest returns ErrorResponse with code 400 Usage (with gin):

context.JSON(BadRequest("invalid data"))

func DefaultCurrencies

func DefaultCurrencies() map[string]string

DefaultCurrencies will return default currencies list for all bots

func DefaultLocalizerBundle

func DefaultLocalizerBundle() *i18n.Bundle

DefaultLocalizerBundle returns new localizer bundle with English as default language

func DefaultLocalizerMatcher

func DefaultLocalizerMatcher() language.Matcher

DefaultLocalizerMatcher returns matcher with English, Russian and Spanish tags

func DefaultLogFormatter

func DefaultLogFormatter() logging.Formatter

DefaultLogFormatter will return default formatter for logs

func ErrorCollector

func ErrorCollector(errorsList ...error) error

ErrorCollector can be used to group several error calls into one call. It is mostly useful in GORM migrations, where you should return only one errors, but several can occur. Error messages are composed into one message. For example:

err := core.ErrorCollector(
	errors.New("first"),
	errors.New("second")
)

// Will output `first < second`
fmt.Println(err.Error())

Example with GORM migration, returns one migration error with all error messages:

return core.ErrorCollector(
	db.CreateTable(models.Account{}, models.Connection{}).Error,
	db.Table("account").AddUniqueIndex("account_key", "channel").Error,
)

func GetCSRFErrorMessage

func GetCSRFErrorMessage(r CSRFErrorReason) string

GetCSRFErrorMessage returns generic error message for CSRFErrorReason in English (useful for logs)

func GetCurrencySymbol added in v1.7.0

func GetCurrencySymbol(code string) string

GetCurrencySymbol returns currency symbol by it's ISO 4127 code. It returns provided currency code in uppercase if currency symbol cannot be found

func GetEntitySHA1

func GetEntitySHA1(v interface{}) (hash string, err error)

GetEntitySHA1 will serialize any value to JSON and return SHA1 hash of this JSON

func GetErrorResponse

func GetErrorResponse(statusCode int, error string) (int, interface{})

GetErrorResponse returns ErrorResponse with specified status code Usage (with gin):

context.JSON(GetErrorResponse(http.StatusPaymentRequired, "Not enough money"))

func GetMGItemData

func GetMGItemData(client *v1.MgClient, url string, caption string) (v1.Item, int, error)

GetMGItemData will upload file to MG by URL and return information about attachable item

func InternalServerError

func InternalServerError(error string) (int, interface{})

InternalServerError returns ErrorResponse with code 500 Usage (with gin):

context.JSON(BadRequest("invalid data"))

func LocalizerBundle added in v1.5.0

func LocalizerBundle(tag language.Tag) *i18n.Bundle

LocalizerBundle returns new localizer bundle provided language as default

func ReplaceMarkdownSymbols

func ReplaceMarkdownSymbols(s string) string

ReplaceMarkdownSymbols will remove markdown symbols from text

Types

type Account

type Account struct {
	ID                  int    `gorm:"primary_key"`
	ConnectionID        int    `gorm:"column:connection_id" json:"connectionId,omitempty"`
	Channel             uint64 `gorm:"column:channel; not null; unique" json:"channel,omitempty"`
	ChannelSettingsHash string `gorm:"column:channel_settings_hash; type:varchar(70)" binding:"max=70"`
	Name                string `gorm:"column:name; type:varchar(40)" json:"name,omitempty" binding:"max=40"`
	Lang                string `gorm:"column:lang; type:varchar(2)" json:"lang,omitempty" binding:"max=2"`
	CreatedAt           time.Time
	UpdatedAt           time.Time
}

Account model

type Accounts

type Accounts []Account

Accounts list

type CSRF

type CSRF struct {
	// contains filtered or unexported fields
}

CSRF struct. Provides CSRF token verification.

func NewCSRF

func NewCSRF(salt, secret, sessionName string, store sessions.Store, abortFunc CSRFAbortFunc, csrfTokenGetter CSRFTokenGetter) *CSRF

NewCSRF creates CSRF struct with specified configuration and session store. GenerateCSRFMiddleware and VerifyCSRFMiddleware returns CSRF middlewares. Salt must be different every time (pass empty salt to use random), secret must be provided, sessionName is optional - pass empty to use default, store will be used to store sessions, abortFunc will be called to return error if token is invalid, csrfTokenGetter will be used to obtain token. Usage (with random salt):

core.NewCSRF("", "super secret", "csrf_session", store, func (c *gin.Context, reason core.CSRFErrorReason) {
	c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid CSRF token"})
}, core.DefaultCSRFTokenGetter)

Note for csrfTokenGetter: if you want to read token from request body (for example, from form field) - don't forget to restore Body data! Body in http.Request is io.ReadCloser instance. Reading CSRF token from form like that:

if t := r.FormValue("csrf_token"); len(t) > 0 {
	return t
}

will close body - and all next middlewares won't be able to read body at all! Use DefaultCSRFTokenGetter as example to implement your own token getter. CSRFErrorReason will be passed to abortFunc and can be used for better error messages.

func (*CSRF) CSRFFromContext

func (x *CSRF) CSRFFromContext(c *gin.Context) string

CSRFFromContext returns csrf token or random token. It shouldn't return empty string because it will make csrf protection useless. e.g. any request without token will work fine, which is inacceptable.

func (*CSRF) GenerateCSRFMiddleware

func (x *CSRF) GenerateCSRFMiddleware() gin.HandlerFunc

GenerateCSRFMiddleware returns gin.HandlerFunc which will generate CSRF token Usage:

engine := gin.New()
csrf := NewCSRF("salt", "secret", "not_found", "incorrect", localizer)
engine.Use(csrf.GenerateCSRFMiddleware())

func (*CSRF) VerifyCSRFMiddleware

func (x *CSRF) VerifyCSRFMiddleware(ignoredMethods []string) gin.HandlerFunc

VerifyCSRFMiddleware verifies CSRF token Usage:

engine := gin.New()
engine.Use(csrf.VerifyCSRFMiddleware())

type CSRFAbortFunc

type CSRFAbortFunc func(*gin.Context, CSRFErrorReason)

CSRFAbortFunc is a callback which

type CSRFErrorReason

type CSRFErrorReason uint8

CSRFErrorReason is a error reason type

const (
	// CSRFErrorNoTokenInSession will be returned if token is not present in session
	CSRFErrorNoTokenInSession CSRFErrorReason = iota

	// CSRFErrorCannotStoreTokenInSession will be returned if middleware cannot store token in session
	CSRFErrorCannotStoreTokenInSession

	// CSRFErrorIncorrectTokenType will be returned if data type of token in session is not string
	CSRFErrorIncorrectTokenType

	// CSRFErrorEmptyToken will be returned if token in session is empty
	CSRFErrorEmptyToken

	// CSRFErrorTokenMismatch will be returned in case of invalid token
	CSRFErrorTokenMismatch
)

type CSRFTokenGetter

type CSRFTokenGetter func(*gin.Context) string

CSRFTokenGetter func type

type Config

type Config struct {
	Version          string            `yaml:"version"`
	LogLevel         logging.Level     `yaml:"log_level"`
	Database         DatabaseConfig    `yaml:"database"`
	SentryDSN        string            `yaml:"sentry_dsn"`
	HTTPServer       HTTPServerConfig  `yaml:"http_server"`
	Debug            bool              `yaml:"debug"`
	UpdateInterval   int               `yaml:"update_interval"`
	ConfigAWS        ConfigAWS         `yaml:"config_aws"`
	TransportInfo    Info              `yaml:"transport_info"`
	HTTPClientConfig *HTTPClientConfig `yaml:"http_client"`
}

Config struct

func NewConfig

func NewConfig(path string) *Config

NewConfig reads configuration file and returns config instance Usage:

NewConfig("config.yml")

func (Config) GetAWSConfig

func (c Config) GetAWSConfig() ConfigAWS

GetAWSConfig AWS configuration

func (*Config) GetConfigData

func (c *Config) GetConfigData(path string) []byte

GetConfigData returns config file data in form of byte sequence

func (Config) GetDBConfig

func (c Config) GetDBConfig() DatabaseConfig

GetDBConfig database configuration

func (Config) GetHTTPClientConfig

func (c Config) GetHTTPClientConfig() *HTTPClientConfig

GetHTTPClientConfig returns http client config

func (Config) GetHTTPConfig

func (c Config) GetHTTPConfig() HTTPServerConfig

GetHTTPConfig server configuration

func (Config) GetLogLevel

func (c Config) GetLogLevel() logging.Level

GetLogLevel log level

func (Config) GetSentryDSN

func (c Config) GetSentryDSN() string

GetSentryDSN sentry connection dsn

func (Config) GetTransportInfo

func (c Config) GetTransportInfo() InfoInterface

GetTransportInfo transport basic data

func (Config) GetUpdateInterval

func (c Config) GetUpdateInterval() int

GetUpdateInterval user data update interval

func (Config) GetVersion

func (c Config) GetVersion() string

GetVersion transport version

func (Config) IsDebug

func (c Config) IsDebug() bool

IsDebug debug flag

func (*Config) LoadConfig

func (c *Config) LoadConfig(path string) *Config

LoadConfig read & load configuration file

func (*Config) LoadConfigFromData

func (c *Config) LoadConfigFromData(data []byte) *Config

LoadConfigFromData loads config from byte sequence

type ConfigAWS

type ConfigAWS struct {
	AccessKeyID     string `yaml:"access_key_id"`
	SecretAccessKey string `yaml:"secret_access_key"`
	Region          string `yaml:"region"`
	Bucket          string `yaml:"bucket"`
	FolderName      string `yaml:"folder_name"`
	ContentType     string `yaml:"content_type"`
}

ConfigAWS struct

type ConfigInterface

type ConfigInterface interface {
	GetVersion() string
	GetSentryDSN() string
	GetLogLevel() logging.Level
	GetHTTPConfig() HTTPServerConfig
	GetDBConfig() DatabaseConfig
	GetAWSConfig() ConfigAWS
	GetTransportInfo() InfoInterface
	GetHTTPClientConfig() *HTTPClientConfig
	GetUpdateInterval() int
	IsDebug() bool
}

ConfigInterface settings data structure

type Connection

type Connection struct {
	ID        int    `gorm:"primary_key"`
	ClientID  string `gorm:"column:client_id; type:varchar(70); not null; unique" json:"clientId,omitempty"`
	Key       string `gorm:"column:api_key; type:varchar(100); not null" json:"api_key,omitempty" binding:"required,max=100"`
	URL       string `gorm:"column:api_url; type:varchar(255); not null" json:"api_url,omitempty" binding:"required,validatecrmurl,max=255"`
	GateURL   string `gorm:"column:mg_url; type:varchar(255); not null;" json:"mg_url,omitempty" binding:"max=255"`
	GateToken string `gorm:"column:mg_token; type:varchar(100); not null; unique" json:"mg_token,omitempty" binding:"max=100"`
	CreatedAt time.Time
	UpdatedAt time.Time
	Active    bool      `json:"active,omitempty"`
	Accounts  []Account `gorm:"foreignkey:ConnectionID"`
}

Connection model

type DatabaseConfig

type DatabaseConfig struct {
	Connection         interface{} `yaml:"connection"`
	Logging            bool        `yaml:"logging"`
	TablePrefix        string      `yaml:"table_prefix"`
	MaxOpenConnections int         `yaml:"max_open_connections"`
	MaxIdleConnections int         `yaml:"max_idle_connections"`
	ConnectionLifetime int         `yaml:"connection_lifetime"`
}

DatabaseConfig struct

type Engine

type Engine struct {
	Localizer
	ORM
	Sentry
	Utils

	PreloadLanguages []language.Tag
	Sessions         sessions.Store
	Config           ConfigInterface
	LogFormatter     logging.Formatter
	// contains filtered or unexported fields
}

Engine struct

func New

func New() *Engine

New Engine instance (must be configured manually, gin can be accessed via engine.Router() directly or engine.ConfigureRouter(...) with callback)

func (*Engine) BuildHTTPClient

func (e *Engine) BuildHTTPClient(replaceDefault ...bool) *Engine

BuildHTTPClient builds HTTP client with provided configuration

func (*Engine) ConfigureRouter

func (e *Engine) ConfigureRouter(callback func(*gin.Engine)) *Engine

ConfigureRouter will call provided callback with current gin.Engine, or panic if engine is not present

func (*Engine) CreateRenderer

func (e *Engine) CreateRenderer(callback func(*Renderer), funcs template.FuncMap) Renderer

CreateRenderer with translation function

func (*Engine) CreateRendererFS

func (e *Engine) CreateRendererFS(box *packr.Box, callback func(*Renderer), funcs template.FuncMap) Renderer

CreateRendererFS with translation function and packr box with templates data

func (*Engine) GenerateCSRFMiddleware

func (e *Engine) GenerateCSRFMiddleware() gin.HandlerFunc

GenerateCSRFMiddleware returns CSRF generator middleware Usage:

engine.Router().Use(engine.GenerateCSRFMiddleware())

func (*Engine) GetCSRFToken

func (e *Engine) GetCSRFToken(c *gin.Context) string

GetCSRFToken returns CSRF token from provided context

func (*Engine) HTTPClient

func (e *Engine) HTTPClient() *http.Client

HTTPClient returns inner http client or default http client

func (*Engine) InitCSRF

func (e *Engine) InitCSRF(secret string, abortFunc CSRFAbortFunc, getter CSRFTokenGetter) *Engine

InitCSRF initializes CSRF middleware. engine.Sessions must be already initialized, use engine.WithCookieStore or engine.WithFilesystemStore for that. Syntax is similar to core.NewCSRF, but you shouldn't pass sessionName, store and salt.

func (*Engine) JobManager added in v1.2.0

func (e *Engine) JobManager() *JobManager

JobManager will return singleton JobManager from Engine

func (*Engine) Logger

func (e *Engine) Logger() LoggerInterface

Logger returns current logger

func (*Engine) Prepare

func (e *Engine) Prepare() *Engine

Prepare engine for start

func (*Engine) Router

func (e *Engine) Router() *gin.Engine

Router will return current gin.Engine or panic if it's not present

func (*Engine) Run

func (e *Engine) Run() error

Run gin.Engine loop, or panic if engine is not present

func (*Engine) SetHTTPClient

func (e *Engine) SetHTTPClient(client *http.Client) *Engine

SetHTTPClient sets HTTP client to engine

func (*Engine) SetLogger added in v1.3.0

func (e *Engine) SetLogger(l LoggerInterface) *Engine

SetLogger sets provided logger instance to engine

func (*Engine) TemplateFuncMap

func (e *Engine) TemplateFuncMap(functions template.FuncMap) template.FuncMap

TemplateFuncMap combines func map for templates

func (*Engine) VerifyCSRFMiddleware

func (e *Engine) VerifyCSRFMiddleware(ignoredMethods []string) gin.HandlerFunc

VerifyCSRFMiddleware returns CSRF verifier middleware Usage:

engine.Router().Use(engine.VerifyCSRFMiddleware(core.DefaultIgnoredMethods))

func (*Engine) WithCookieSessions

func (e *Engine) WithCookieSessions(keyLength ...int) *Engine

WithCookieSessions generates new CookieStore with optional key length. Default key length is 32 bytes.

func (*Engine) WithFilesystemSessions

func (e *Engine) WithFilesystemSessions(path string, keyLength ...int) *Engine

WithFilesystemSessions generates new FilesystemStore with optional key length. Default key length is 32 bytes.

type ErrorHandlerFunc

type ErrorHandlerFunc func(recovery interface{}, c *gin.Context)

ErrorHandlerFunc will handle errors

type ErrorResponse

type ErrorResponse struct {
	Error string `json:"error"`
}

ErrorResponse struct

type ErrorsResponse added in v1.6.0

type ErrorsResponse struct {
	Error []string `json:"error"`
}

ErrorsResponse struct

type HTTPClientBuilder

type HTTPClientBuilder struct {
	// contains filtered or unexported fields
}

HTTPClientBuilder builds http client with mocks (if necessary) and timeout. Example:

// Build HTTP client with timeout = 10 sec, without SSL certificates verification and with mocked google.com
client, err := NewHTTPClientBuilder().
	SetTimeout(10).
	SetMockAddress("api_mock:3004").
	AddMockedDomain("google.com").
	SetSSLVerification(false).
	Build()

if err != nil {
	fmt.Print(err)
}

// Actual response will be returned from "api_mock:3004" (it should provide any ssl certificate)
if resp, err := client.Get("https://google.com"); err == nil {
	if data, err := ioutil.ReadAll(resp.Body); err == nil {
		fmt.Printf("Data: %s", string(data))
	} else {
		fmt.Print(err)
	}
} else {
	fmt.Print(err)
}

func NewHTTPClientBuilder

func NewHTTPClientBuilder() *HTTPClientBuilder

NewHTTPClientBuilder returns HTTPClientBuilder with default values

func (*HTTPClientBuilder) AddMockedDomain

func (b *HTTPClientBuilder) AddMockedDomain(domain string) *HTTPClientBuilder

AddMockedDomain adds new mocked domain

func (*HTTPClientBuilder) Build

func (b *HTTPClientBuilder) Build(replaceDefault ...bool) (*http.Client, error)

Build builds client, pass true to replace http.DefaultClient with generated one

func (*HTTPClientBuilder) FromConfig

func (b *HTTPClientBuilder) FromConfig(config *HTTPClientConfig) *HTTPClientBuilder

FromConfig fulfills mock configuration from HTTPClientConfig

func (*HTTPClientBuilder) FromEngine

func (b *HTTPClientBuilder) FromEngine(engine *Engine) *HTTPClientBuilder

FromEngine fulfills mock configuration from ConfigInterface inside Engine

func (*HTTPClientBuilder) ReplaceDefault

func (b *HTTPClientBuilder) ReplaceDefault() *HTTPClientBuilder

ReplaceDefault replaces default client and transport with generated ones

func (*HTTPClientBuilder) RestoreDefault

func (b *HTTPClientBuilder) RestoreDefault() *HTTPClientBuilder

RestoreDefault restores default client and transport after replacement

func (*HTTPClientBuilder) SetLogging

func (b *HTTPClientBuilder) SetLogging(flag bool) *HTTPClientBuilder

SetLogging enables or disables logging in mocks

func (*HTTPClientBuilder) SetMockAddress

func (b *HTTPClientBuilder) SetMockAddress(address string) *HTTPClientBuilder

SetMockAddress sets mock address

func (*HTTPClientBuilder) SetMockedDomains

func (b *HTTPClientBuilder) SetMockedDomains(domains []string) *HTTPClientBuilder

SetMockedDomains sets mocked domains from slice

func (*HTTPClientBuilder) SetSSLVerification

func (b *HTTPClientBuilder) SetSSLVerification(enabled bool) *HTTPClientBuilder

SetSSLVerification enables or disables SSL certificates verification in client

func (*HTTPClientBuilder) SetTimeout

func (b *HTTPClientBuilder) SetTimeout(timeout time.Duration) *HTTPClientBuilder

SetTimeout sets timeout for http client

func (*HTTPClientBuilder) WithLogger

func (b *HTTPClientBuilder) WithLogger(logger LoggerInterface) *HTTPClientBuilder

WithLogger sets provided logger into HTTPClientBuilder

type HTTPClientConfig

type HTTPClientConfig struct {
	Timeout         time.Duration `yaml:"timeout"`
	SSLVerification *bool         `yaml:"ssl_verification"`
	MockAddress     string        `yaml:"mock_address"`
	MockedDomains   []string      `yaml:"mocked_domains"`
}

HTTPClientConfig struct

func (*HTTPClientConfig) IsSSLVerificationEnabled

func (h *HTTPClientConfig) IsSSLVerificationEnabled() bool

IsSSLVerificationEnabled returns SSL verification flag (default is true)

type HTTPServerConfig

type HTTPServerConfig struct {
	Host   string `yaml:"host"`
	Listen string `yaml:"listen"`
}

HTTPServerConfig struct

type Info

type Info struct {
	Name     string `yaml:"name"`
	Code     string `yaml:"code"`
	LogoPath string `yaml:"logo_path"`
}

Info struct

func (Info) GetCode

func (t Info) GetCode() string

GetCode transport code

func (Info) GetLogoPath

func (t Info) GetLogoPath() string

GetLogoPath transport logo

func (Info) GetName

func (t Info) GetName() string

GetName transport name

type InfoInterface

type InfoInterface interface {
	GetName() string
	GetCode() string
	GetLogoPath() string
}

InfoInterface transport settings data structure

type Job added in v1.2.0

type Job struct {
	Command      JobFunc
	ErrorHandler JobErrorHandler
	PanicHandler JobPanicHandler
	Interval     time.Duration

	Regular bool
	// contains filtered or unexported fields
}

Job represents single job. Regular job will be executed every Interval.

type JobErrorHandler added in v1.2.0

type JobErrorHandler func(string, error, JobLogFunc)

JobErrorHandler is a function to handle jobs errors. First argument is a job name.

func DefaultJobErrorHandler added in v1.2.0

func DefaultJobErrorHandler() JobErrorHandler

DefaultJobErrorHandler returns default error handler for a job

type JobFunc added in v1.2.0

type JobFunc func(JobLogFunc) error

JobFunc is empty func which should be executed in a parallel goroutine

type JobLogFunc added in v1.2.0

type JobLogFunc func(string, logging.Level, ...interface{})

JobLogFunc is a function which logs data from job

type JobManager added in v1.2.0

type JobManager struct {
	// contains filtered or unexported fields
}

JobManager controls jobs execution flow. Jobs can be added just for later use (e.g. JobManager can be used as singleton), or jobs can be executed as regular jobs. Example initialization:

    manager := NewJobManager().
		SetLogger(logger).
		SetLogging(false)
	_ = manager.RegisterJob("updateTokens", &Job{
		Command: func(logFunc JobLogFunc) error {
			// logic goes here...
			logFunc("All tokens were updated successfully", logging.INFO)
			return nil
		},
		ErrorHandler: DefaultJobErrorHandler(),
		PanicHandler: DefaultJobPanicHandler(),
		Interval:     time.Hour * 3,
		Regular:      true,
	})
	manager.Start()

func NewJobManager added in v1.2.0

func NewJobManager() *JobManager

NewJobManager is a JobManager constructor

func (*JobManager) FetchJob added in v1.2.0

func (j *JobManager) FetchJob(name string) (value *Job, ok bool)

FetchJob fetches already exist job

func (*JobManager) RegisterJob added in v1.2.0

func (j *JobManager) RegisterJob(name string, job *Job) error

RegisterJob registers new job

func (*JobManager) RunJob added in v1.2.0

func (j *JobManager) RunJob(name string) error

RunJob starts provided regular job if it's exists. It's async operation and error returns only of job wasn't executed at all.

func (*JobManager) RunJobOnce added in v1.2.0

func (j *JobManager) RunJobOnce(name string) error

RunJobOnce starts provided job once if it exists. It's also async.

func (*JobManager) RunJobOnceSync added in v1.2.0

func (j *JobManager) RunJobOnceSync(name string) error

RunJobOnceSync starts provided job once in current goroutine if job exists. Will wait for job to end it's work.

func (*JobManager) SetLogger added in v1.2.0

func (j *JobManager) SetLogger(logger LoggerInterface) *JobManager

SetLogger sets logger into JobManager

func (*JobManager) SetLogging added in v1.2.0

func (j *JobManager) SetLogging(enableLogging bool) *JobManager

SetLogging enables or disables JobManager logging

func (*JobManager) Start added in v1.2.0

func (j *JobManager) Start()

Start all jobs in the manager

func (*JobManager) StopJob added in v1.2.0

func (j *JobManager) StopJob(name string) error

StopJob stops provided regular regular job if it's exists.

func (*JobManager) UnregisterJob added in v1.2.0

func (j *JobManager) UnregisterJob(name string) error

UnregisterJob unregisters job if it's exists. Returns error if job doesn't exist.

func (*JobManager) UpdateJob added in v1.2.0

func (j *JobManager) UpdateJob(name string, job *Job) error

UpdateJob updates job

type JobPanicHandler added in v1.2.0

type JobPanicHandler func(string, interface{}, JobLogFunc)

JobPanicHandler is a function to handle jobs panics. First argument is a job name.

func DefaultJobPanicHandler added in v1.2.0

func DefaultJobPanicHandler() JobPanicHandler

DefaultJobPanicHandler returns default panic handler for a job

type Localizer

type Localizer struct {
	TranslationsBox *packr.Box

	LocaleMatcher    language.Matcher
	LanguageTag      language.Tag
	TranslationsPath string
	// contains filtered or unexported fields
}

Localizer struct

func GetContextLocalizer added in v1.5.0

func GetContextLocalizer(c *gin.Context) (*Localizer, bool)

GetContextLocalizer returns localizer from context if it exist there

func MustGetContextLocalizer added in v1.5.0

func MustGetContextLocalizer(c *gin.Context) *Localizer

MustGetContextLocalizer returns Localizer instance if it exists in provided context. Panics otherwise.

func NewLocalizer

func NewLocalizer(locale language.Tag, matcher language.Matcher, translationsPath string) *Localizer

NewLocalizer returns localizer instance with specified parameters. Usage:

NewLocalizer(language.English, DefaultLocalizerMatcher(), "translations")

func NewLocalizerFS added in v1.3.0

func NewLocalizerFS(locale language.Tag, matcher language.Matcher, translationsBox *packr.Box) *Localizer

NewLocalizerFS returns localizer instance with specified parameters. *packr.Box should be used instead of directory. Usage:

NewLocalizerFS(language.English, DefaultLocalizerMatcher(), translationsBox)

TODO This code should be covered with tests.

func (*Localizer) BadRequestLocalized

func (l *Localizer) BadRequestLocalized(err string) (int, interface{})

BadRequestLocalized is same as BadRequest(string), but passed string will be localized

func (*Localizer) FetchLanguage deprecated

func (l *Localizer) FetchLanguage()

FetchLanguage will load language from tag

Deprecated: Use `(*core.Localizer).LoadTranslations()` instead

func (*Localizer) GetLocalizedMessage

func (l *Localizer) GetLocalizedMessage(messageID string) string

GetLocalizedMessage will return localized message by it's ID. It doesn't use `Must` prefix in order to keep BC.

func (*Localizer) GetLocalizedTemplateMessage

func (l *Localizer) GetLocalizedTemplateMessage(messageID string, templateData map[string]interface{}) string

GetLocalizedTemplateMessage will return localized message with specified data. It doesn't use `Must` prefix in order to keep BC. It uses text/template syntax: https://golang.org/pkg/text/template/

func (*Localizer) LoadTranslations

func (l *Localizer) LoadTranslations()

LoadTranslations will load all translation files from translations directory or from embedded box

func (*Localizer) LocalizationFuncMap

func (l *Localizer) LocalizationFuncMap() template.FuncMap

LocalizationFuncMap returns template.FuncMap (html template is used) with one method - trans Usage in code:

engine := gin.New()
engine.FuncMap = localizer.LocalizationFuncMap()

or (with multitemplate)

renderer := multitemplate.NewRenderer()
funcMap := localizer.LocalizationFuncMap()
renderer.AddFromFilesFuncs("index", funcMap, "template/index.html")

funcMap must be passed for every .AddFromFilesFuncs call Usage in templates:

<p class="info">{{"need_login_msg" | trans}}

You can borrow FuncMap from this method and add your functions to it.

func (*Localizer) LocalizationMiddleware

func (l *Localizer) LocalizationMiddleware() gin.HandlerFunc

LocalizationMiddleware returns gin.HandlerFunc which will set localizer language by Accept-Language header Result Localizer instance will share it's internal data (translations, bundles, etc) with instance which was used to append middleware to gin. Because of that all Localizer instances from this middleware will share *same* mutex. This mutex is used to wrap i18n.Bundle methods (those aren't goroutine-safe to use). Usage:

engine := gin.New()
localizer := NewLocalizer("en", DefaultLocalizerBundle(), DefaultLocalizerMatcher(), "translations")
engine.Use(localizer.LocalizationMiddleware())

func (*Localizer) Localize added in v1.5.0

func (l *Localizer) Localize(messageID string) (string, error)

Localize will return localized message by it's ID, or error if message wasn't found

func (*Localizer) LocalizeTemplateMessage added in v1.5.0

func (l *Localizer) LocalizeTemplateMessage(messageID string, templateData map[string]interface{}) (string, error)

LocalizeTemplateMessage will return localized message with specified data, or error if message wasn't found It uses text/template syntax: https://golang.org/pkg/text/template/

func (*Localizer) Preload added in v1.5.0

func (l *Localizer) Preload(tags []language.Tag)

Preload provided languages (so they will not be loaded every time in middleware)

func (*Localizer) SetLanguage

func (l *Localizer) SetLanguage(tag language.Tag)

SetLanguage will change language using language tag

func (*Localizer) SetLocale

func (l *Localizer) SetLocale(al string)

SetLocale will change language for current localizer

type Logger added in v1.3.0

type Logger struct {
	// contains filtered or unexported fields
}

Logger component. Uses github.com/op/go-logging under the hood. This logger can prevent any write operations (disabled by default, use .Exclusive() method to enable)

func NewLogger

func NewLogger(transportCode string, logLevel logging.Level, logFormat logging.Formatter) *Logger

NewLogger will create new goroutine-safe logger with specified formatter. Usage:

logger := NewLogger("telegram", logging.ERROR, DefaultLogFormatter())

func (*Logger) Critical added in v1.3.0

func (l *Logger) Critical(args ...interface{})

Critical logs a message using CRITICAL as log level.

func (*Logger) Criticalf added in v1.3.0

func (l *Logger) Criticalf(format string, args ...interface{})

Criticalf logs a message using CRITICAL as log level.

func (*Logger) Debug added in v1.3.0

func (l *Logger) Debug(args ...interface{})

Debug logs a message using DEBUG as log level.

func (*Logger) Debugf added in v1.3.0

func (l *Logger) Debugf(format string, args ...interface{})

Debugf logs a message using DEBUG as log level.

func (*Logger) Error added in v1.3.0

func (l *Logger) Error(args ...interface{})

Error logs a message using ERROR as log level.

func (*Logger) Errorf added in v1.3.0

func (l *Logger) Errorf(format string, args ...interface{})

Errorf logs a message using ERROR as log level.

func (*Logger) Exclusive added in v1.3.0

func (l *Logger) Exclusive() *Logger

Exclusive makes logger goroutine-safe

func (*Logger) Fatal added in v1.3.0

func (l *Logger) Fatal(args ...interface{})

Fatal is equivalent to l.Critical(fmt.Sprint()) followed by a call to os.Exit(1).

func (*Logger) Fatalf added in v1.3.0

func (l *Logger) Fatalf(format string, args ...interface{})

Fatalf is equivalent to l.Critical followed by a call to os.Exit(1).

func (*Logger) Info added in v1.3.0

func (l *Logger) Info(args ...interface{})

Info logs a message using INFO as log level.

func (*Logger) Infof added in v1.3.0

func (l *Logger) Infof(format string, args ...interface{})

Infof logs a message using INFO as log level.

func (*Logger) Notice added in v1.3.0

func (l *Logger) Notice(args ...interface{})

Notice logs a message using NOTICE as log level.

func (*Logger) Noticef added in v1.3.0

func (l *Logger) Noticef(format string, args ...interface{})

Noticef logs a message using NOTICE as log level.

func (*Logger) Panic added in v1.3.0

func (l *Logger) Panic(args ...interface{})

Panic is equivalent to l.Critical(fmt.Sprint()) followed by a call to panic().

func (*Logger) Panicf added in v1.3.0

func (l *Logger) Panicf(format string, args ...interface{})

Panicf is equivalent to l.Critical followed by a call to panic().

func (*Logger) Warning added in v1.3.0

func (l *Logger) Warning(args ...interface{})

Warning logs a message using WARNING as log level.

func (*Logger) Warningf added in v1.3.0

func (l *Logger) Warningf(format string, args ...interface{})

Warningf logs a message using WARNING as log level.

type LoggerInterface added in v1.3.0

type LoggerInterface interface {
	Fatal(args ...interface{})
	Fatalf(format string, args ...interface{})
	Panic(args ...interface{})
	Panicf(format string, args ...interface{})
	Critical(args ...interface{})
	Criticalf(format string, args ...interface{})
	Error(args ...interface{})
	Errorf(format string, args ...interface{})
	Warning(args ...interface{})
	Warningf(format string, args ...interface{})
	Notice(args ...interface{})
	Noticef(format string, args ...interface{})
	Info(args ...interface{})
	Infof(format string, args ...interface{})
	Debug(args ...interface{})
	Debugf(format string, args ...interface{})
}

LoggerInterface contains methods which should be present in logger implementation

type Migrate

type Migrate struct {
	GORMigrate *gormigrate.Gormigrate
	// contains filtered or unexported fields
}

Migrate tool, decorates gormigrate.Migration in order to provide better interface & versioning

func Migrations

func Migrations() *Migrate

Migrations returns default migrate

func (*Migrate) Add

func (m *Migrate) Add(migration *gormigrate.Migration)

Add GORMigrate to migrate

func (*Migrate) Close

func (m *Migrate) Close() error

Close db connection

func (*Migrate) Current

func (m *Migrate) Current() string

Current migration version

func (*Migrate) Migrate

func (m *Migrate) Migrate() error

Migrate all, including schema initialization

func (*Migrate) MigrateNextTo

func (m *Migrate) MigrateNextTo(version string) error

MigrateNextTo migrate to next version from specified version

func (*Migrate) MigratePreviousTo

func (m *Migrate) MigratePreviousTo(version string) error

MigratePreviousTo migrate to previous version from specified version

func (*Migrate) MigrateTo

func (m *Migrate) MigrateTo(version string) error

MigrateTo specified version

func (*Migrate) NextFrom

func (m *Migrate) NextFrom(version string) (string, error)

NextFrom returns next version from passed version

func (*Migrate) PreviousFrom

func (m *Migrate) PreviousFrom(version string) (string, error)

PreviousFrom returns previous version from passed version

func (*Migrate) Rollback

func (m *Migrate) Rollback() error

Rollback all migrations

func (*Migrate) RollbackTo

func (m *Migrate) RollbackTo(version string) error

RollbackTo specified version

func (*Migrate) SetDB

func (m *Migrate) SetDB(db *gorm.DB) *Migrate

SetDB to migrate

type MigrationInfo

type MigrationInfo struct {
	ID string `gorm:"column:id; type:varchar(255)"`
}

MigrationInfo with migration info

func (MigrationInfo) TableName

func (MigrationInfo) TableName() string

TableName for MigrationInfo

type NewMigrationCommand

type NewMigrationCommand struct {
	Directory string `short:"d" long:"directory" default:"./migrations" description:"Directory where migration will be created"`
}

NewMigrationCommand struct

func (*NewMigrationCommand) Execute

func (x *NewMigrationCommand) Execute(args []string) error

Execute migration generator command

func (*NewMigrationCommand) FileExists

func (x *NewMigrationCommand) FileExists(filename string) bool

FileExists returns true if provided file exist and it's not directory

type ORM

type ORM struct {
	DB *gorm.DB
}

ORM struct

func NewORM

func NewORM(config DatabaseConfig) *ORM

NewORM will init new database connection

func (*ORM) CloseDB

func (orm *ORM) CloseDB()

CloseDB close database connection

type Renderer

type Renderer struct {
	multitemplate.Renderer
	TemplatesBox *packr.Box
	FuncMap      template.FuncMap
	// contains filtered or unexported fields
}

Renderer wraps multitemplate.Renderer in order to make it easier to use

func NewDynamicRenderer

func NewDynamicRenderer(funcMap template.FuncMap) Renderer

NewDynamicRenderer is a Renderer constructor with multitemplate.DynamicRender

func NewRenderer

func NewRenderer(funcMap template.FuncMap) Renderer

NewRenderer is a Renderer constructor

func NewStaticRenderer

func NewStaticRenderer(funcMap template.FuncMap) Renderer

NewStaticRenderer is a Renderer constructor with multitemplate.Render

func (*Renderer) Push

func (r *Renderer) Push(name string, files ...string) *template.Template

Push is an AddFromFilesFuncs wrapper

type Sentry

type Sentry struct {
	TaggedTypes  SentryTaggedTypes
	Stacktrace   bool
	DefaultError string
	Localizer    *Localizer
	Logger       LoggerInterface
	Client       stacktrace.RavenClientInterface
}

Sentry struct. Holds SentryTaggedStruct list

func NewSentry

func NewSentry(sentryDSN string, defaultError string, taggedTypes SentryTaggedTypes, logger LoggerInterface, localizer *Localizer) *Sentry

NewSentry constructor

func (*Sentry) ErrorCaptureHandler

func (s *Sentry) ErrorCaptureHandler() ErrorHandlerFunc

ErrorCaptureHandler will generate error data and send it to sentry

func (*Sentry) ErrorLogger

func (s *Sentry) ErrorLogger() ErrorHandlerFunc

ErrorLogger logs basic errors

func (*Sentry) ErrorMiddleware

func (s *Sentry) ErrorMiddleware() gin.HandlerFunc

ErrorMiddleware returns error handlers, attachable to gin.Engine

func (*Sentry) ErrorResponseHandler

func (s *Sentry) ErrorResponseHandler() ErrorHandlerFunc

ErrorResponseHandler will be executed in case of any unexpected error

func (*Sentry) PanicLogger

func (s *Sentry) PanicLogger() ErrorHandlerFunc

PanicLogger logs panic

type SentryTagged

type SentryTagged interface {
	BuildTags(interface{}) (map[string]string, error)
	GetContextKey() string
	GetTags() SentryTags
	GetName() string
}

SentryTagged interface for both tagged scalar and struct

type SentryTaggedScalar

type SentryTaggedScalar struct {
	SentryTaggedStruct
	Name string
}

SentryTaggedScalar variable from context

func NewTaggedScalar

func NewTaggedScalar(sample interface{}, ginCtxKey string, name string) *SentryTaggedScalar

NewTaggedScalar constructor

func (*SentryTaggedScalar) BuildTags

func (t *SentryTaggedScalar) BuildTags(v interface{}) (items map[string]string, err error)

BuildTags returns map with single item in this format: <tag name> => <scalar value>

func (*SentryTaggedScalar) Get

func (t *SentryTaggedScalar) Get(v interface{}) (value string, err error)

Get will extract property string representation from specified object. It will be properly formatted.

func (*SentryTaggedScalar) GetContextKey

func (t *SentryTaggedScalar) GetContextKey() string

GetContextKey is getter for GinContextKey

func (*SentryTaggedScalar) GetName

func (t *SentryTaggedScalar) GetName() string

GetName is getter for Name (tag name for scalar)

func (*SentryTaggedScalar) GetTags

func (t *SentryTaggedScalar) GetTags() SentryTags

GetTags is useless for SentryTaggedScalar

type SentryTaggedStruct

type SentryTaggedStruct struct {
	Type          reflect.Type
	GinContextKey string
	Tags          SentryTags
}

SentryTaggedStruct holds information about type, it's key in gin.Context (for middleware), and it's properties

func NewTaggedStruct

func NewTaggedStruct(sample interface{}, ginCtxKey string, tags map[string]string) *SentryTaggedStruct

NewTaggedStruct constructor

func (*SentryTaggedStruct) AddTag

func (t *SentryTaggedStruct) AddTag(name string, property string) *SentryTaggedStruct

AddTag will add tag with property name which holds tag in object

func (*SentryTaggedStruct) BuildTags

func (t *SentryTaggedStruct) BuildTags(v interface{}) (tags map[string]string, err error)

BuildTags will extract tags for Sentry from specified object

func (*SentryTaggedStruct) GetContextKey

func (t *SentryTaggedStruct) GetContextKey() string

GetContextKey is GinContextKey getter

func (*SentryTaggedStruct) GetName

func (t *SentryTaggedStruct) GetName() string

GetName is useless for SentryTaggedStruct

func (*SentryTaggedStruct) GetProperty

func (t *SentryTaggedStruct) GetProperty(v interface{}, property string) (name string, value string, err error)

GetProperty will extract property string representation from specified object. It will be properly formatted.

func (*SentryTaggedStruct) GetTags

func (t *SentryTaggedStruct) GetTags() SentryTags

GetTags is Tags getter

type SentryTaggedTypes

type SentryTaggedTypes []SentryTagged

SentryTaggedTypes list

type SentryTags

type SentryTags map[string]string

SentryTags list for SentryTaggedStruct. Format: name => property name

type TranslationsExtractor

type TranslationsExtractor struct {
	TranslationsBox  *packr.Box
	TranslationsPath string
	// contains filtered or unexported fields
}

TranslationsExtractor is a tool to load raw translations data from files or from box. It is feasible to be used in tests in order to check translation files correctness. The easiest way to check correctness is to check keys in translations. TranslationsExtractor IS NOT supposed to check correctness of translations - it's just an extractor. Translations can be checked manually, or via external library like https://github.com/google/go-cmp

func NewTranslationsExtractor

func NewTranslationsExtractor(fileNameTemplate string) *TranslationsExtractor

NewTranslationsExtractor constructor. Use "translate.{}.yml" as template if your translations are named like "translate.en.yml"

func (*TranslationsExtractor) GetMapKeys

func (t *TranslationsExtractor) GetMapKeys(data map[string]interface{}) []string

GetMapKeys returns sorted map keys from map[string]interface{} - useful to check keys in several translation files

func (*TranslationsExtractor) LoadLocale

func (t *TranslationsExtractor) LoadLocale(locale string) (map[string]interface{}, error)

LoadLocale returns translation file data with provided locale

func (*TranslationsExtractor) LoadLocaleKeys

func (t *TranslationsExtractor) LoadLocaleKeys(locale string) ([]string, error)

LoadLocaleKeys returns only sorted keys from translation file

type User

type User struct {
	ID           int    `gorm:"primary_key"`
	ExternalID   string `gorm:"column:external_id; type:varchar(255); not null; unique"`
	UserPhotoURL string `gorm:"column:user_photo_url; type:varchar(255)" binding:"max=255"`
	UserPhotoID  string `gorm:"column:user_photo_id; type:varchar(100)" binding:"max=100"`
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

User model

func (User) TableName

func (User) TableName() string

TableName will return table name for User It will not work if User is not embedded, but mapped as another type

type MyUser User // will not work

but

type MyUser struct { // will work
    User
}

type Utils

type Utils struct {
	IsDebug      bool
	TokenCounter uint32
	ConfigAWS    ConfigAWS
	Logger       LoggerInterface
	// contains filtered or unexported fields
}

Utils service object

func NewUtils

func NewUtils(awsConfig ConfigAWS, logger LoggerInterface, debug bool) *Utils

NewUtils will create new Utils instance

func (*Utils) GenerateToken

func (u *Utils) GenerateToken() string

GenerateToken will generate long pseudo-random string.

func (*Utils) GetAPIClient

func (u *Utils) GetAPIClient(url, key string) (*v5.Client, int, error)

GetAPIClient will initialize retailCRM api client from url and key

func (*Utils) RemoveTrailingSlash

func (u *Utils) RemoveTrailingSlash(crmURL string) string

RemoveTrailingSlash will remove slash at the end of any string

func (*Utils) UploadUserAvatar

func (u *Utils) UploadUserAvatar(url string) (picURLs3 string, err error)

UploadUserAvatar will upload avatar for user

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL