<commit_before>package l10n

import (
	"fmt"
	"net/http"
	"os"
	"path"
	"strings"

	"github.com/qor/qor"
	"github.com/qor/qor/admin"
	"github.com/qor/qor/roles"
	"github.com/qor/qor/utils"
)

var Global = "en-US"

type Interface interface {
	IsGlobal() bool
	SetLocale(locale string)
}

type Locale struct {
	LanguageCode string `sql:"size:6" gorm:"primary_key"`
}

func (l Locale) IsGlobal() bool {
	return l.LanguageCode == Global
}

func (l *Locale) SetLocale(locale string) {
	l.LanguageCode = locale
}

type AvailableLocalesInterface interface {
	AvailableLocales() []string
}

type ViewableLocalesInterface interface {
	ViewableLocales() []string
}

type EditableLocalesInterface interface {
	EditableLocales() []string
}

func GetAvailableLocales(req *http.Request, currentUser qor.CurrentUser) []string {
	if user, ok := currentUser.(ViewableLocalesInterface); ok {
		return user.ViewableLocales()
	}

	if user, ok := currentUser.(AvailableLocalesInterface); ok {
		return user.AvailableLocales()
	}
	return []string{}
}

func GetEditableLocales(req *http.Request, currentUser qor.CurrentUser) []string {
	if user, ok := currentUser.(EditableLocalesInterface); ok {
		return user.EditableLocales()
	}

	if user, ok := currentUser.(AvailableLocalesInterface); ok {
		return user.AvailableLocales()
	}
	return []string{}
}

func getLocaleFromContext(context *qor.Context) string {
	if locale := utils.GetLocale(context); locale != "" {
		return locale
	}

	return Global
}

func (l *Locale) InjectQorAdmin(res *admin.Resource) {
	for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") {
		admin.RegisterViewPath(path.Join(gopath, "src/github.com/qor/qor/l10n/views"))
	}

	if res.Config == nil {
		res.Config = &admin.Config{}
	}
	if res.Config.Permission == nil {
		res.Config.Permission = roles.NewPermission()
	}

	res.Meta(&admin.Meta{Name: "LanguageCode", Type: "hidden"})

	res.Config.Theme = "l10n"
	res.Config.Permission.Allow(roles.CRUD, "locale_admin").Allow(roles.Read, "locale_reader")

	router := res.GetAdmin().GetRouter()
	router.Use(func(context *admin.Context, middleware *admin.Middleware) {
		context.SetDB(context.GetDB().Set("l10n:locale", getLocaleFromContext(context.Context)))
		middleware.Next(context)
	})

	res.GetAdmin().RegisterFuncMap("current_locale", func(context admin.Context) string {
		return getLocaleFromContext(context.Context)
	})

	res.GetAdmin().RegisterFuncMap("viewable_locales", func(context admin.Context) []string {
		return GetAvailableLocales(context.Request, context.CurrentUser)
	})

	res.GetAdmin().RegisterFuncMap("editable_locales", func(context admin.Context) []string {
		return GetEditableLocales(context.Request, context.CurrentUser)
	})

	res.GetAdmin().RegisterFuncMap("createable_locales", func(context admin.Context) []string {
		editableLocales := GetEditableLocales(context.Request, context.CurrentUser)
		if _, ok := context.Resource.Value.(LocaleCreateableInterface); ok {
			return editableLocales
		} else {
			for _, locale := range editableLocales {
				if locale == Global {
					return []string{Global}
				}
			}
		}
		return []string{}
	})

	res.GetAdmin().RegisterFuncMap("locales_of_resource", func(resource interface{}, context admin.Context) []map[string]interface{} {
		scope := context.GetDB().NewScope(resource)
		var languageCodes []string
		context.GetDB().New().Set("l10n:mode", "unscoped").Model(resource).Where(fmt.Sprintf("%v = ?", scope.PrimaryKey()), scope.PrimaryKeyValue()).Pluck("language_code", &languageCodes)

		var results []map[string]interface{}
		availableLocales := GetAvailableLocales(context.Request, context.CurrentUser)
	OUT:
		for _, locale := range availableLocales {
			for _, localized := range languageCodes {
				if locale == localized {
					results = append(results, map[string]interface{}{"locale": locale, "localized": true})
					continue OUT
				}
			}
			results = append(results, map[string]interface{}{"locale": locale, "localized": false})
		}
		return results
	})

	role := res.Config.Permission.Role
	if _, ok := role.Get("locale_admin"); !ok {
		role.Register("locale_admin", func(req *http.Request, currentUser qor.CurrentUser) bool {
			currentLocale := getLocaleFromContext(&qor.Context{Request: req})
			for _, locale := range GetEditableLocales(req, currentUser) {
				if locale == currentLocale {
					return true
				}
			}
			return false
		})

		role.Register("locale_reader", func(req *http.Request, currentUser qor.CurrentUser) bool {
			currentLocale := getLocaleFromContext(&qor.Context{Request: req})<commit_msg>Add some comments for l10n<commit_after>package l10n

import (
	"fmt"
	"net/http"
	"os"
	"path"
	"strings"

	"github.com/qor/qor"
	"github.com/qor/qor/admin"
	"github.com/qor/qor/roles"
	"github.com/qor/qor/utils"
)

var Global = "en-US"

type Interface interface {
	IsGlobal() bool
	SetLocale(locale string)
}

type Locale struct {
	LanguageCode string `sql:"size:6" gorm:"primary_key"`
}

func (l Locale) IsGlobal() bool {
	return l.LanguageCode == Global
}

func (l *Locale) SetLocale(locale string) {
	l.LanguageCode = locale
}

type AvailableLocalesInterface interface {
	AvailableLocales() []string
}

type ViewableLocalesInterface interface {
	ViewableLocales() []string
}

type EditableLocalesInterface interface {
	EditableLocales() []string
}

func GetAvailableLocales(req *http.Request, currentUser qor.CurrentUser) []string {
	if user, ok := currentUser.(ViewableLocalesInterface); ok {
		return user.ViewableLocales()
	}

	if user, ok := currentUser.(AvailableLocalesInterface); ok {
		return user.AvailableLocales()
	}
	return []string{}
}

func GetEditableLocales(req *http.Request, currentUser qor.CurrentUser) []string {
	if user, ok := currentUser.(EditableLocalesInterface); ok {
		return user.EditableLocales()
	}

	if user, ok := currentUser.(AvailableLocalesInterface); ok {
		return user.AvailableLocales()
	}
	return []string{}
}

func getLocaleFromContext(context *qor.Context) string {
	if locale := utils.GetLocale(context); locale != "" {
		return locale
	}

	return Global
}

func (l *Locale) InjectQorAdmin(res *admin.Resource) {
	for _, gopath := range strings.Split(os.Getenv("GOPATH"), ":") {
		admin.RegisterViewPath(path.Join(gopath, "src/github.com/qor/qor/l10n/views"))
	}

	if res.Config == nil {
		res.Config = &admin.Config{}
	}
	if res.Config.Permission == nil {
		res.Config.Permission = roles.NewPermission()
	}

	res.Meta(&admin.Meta{Name: "LanguageCode", Type: "hidden"})

	res.Config.Theme = "l10n"
	res.Config.Permission.Allow(roles.CRUD, "locale_admin").Allow(roles.Read, "locale_reader")

	Admin := res.GetAdmin()

	// Middleware
	router := Admin.GetRouter()
	router.Use(func(context *admin.Context, middleware *admin.Middleware) {
		context.SetDB(context.GetDB().Set("l10n:locale", getLocaleFromContext(context.Context)))
		middleware.Next(context)
	})

	// FunMap
	Admin.RegisterFuncMap("current_locale", func(context admin.Context) string {
		return getLocaleFromContext(context.Context)
	})

	Admin.RegisterFuncMap("viewable_locales", func(context admin.Context) []string {
		return GetAvailableLocales(context.Request, context.CurrentUser)
	})

	Admin.RegisterFuncMap("editable_locales", func(context admin.Context) []string {
		return GetEditableLocales(context.Request, context.CurrentUser)
	})

	Admin.RegisterFuncMap("createable_locales", func(context admin.Context) []string {
		editableLocales := GetEditableLocales(context.Request, context.CurrentUser)
		if _, ok := context.Resource.Value.(LocaleCreateableInterface); ok {
			return editableLocales
		} else {
			for _, locale := range editableLocales {
				if locale == Global {
					return []string{Global}
				}
			}
		}
		return []string{}
	})

	Admin.RegisterFuncMap("locales_of_resource", func(resource interface{}, context admin.Context) []map[string]interface{} {
		scope := context.GetDB().NewScope(resource)
		var languageCodes []string
		context.GetDB().New().Set("l10n:mode", "unscoped").Model(resource).Where(fmt.Sprintf("%v = ?", scope.PrimaryKey()), scope.PrimaryKeyValue()).Pluck("language_code", &languageCodes)

		var results []map[string]interface{}
		availableLocales := GetAvailableLocales(context.Request, context.CurrentUser)
	OUT:
		for _, locale := range availableLocales {
			for _, localized := range languageCodes {
				if locale == localized {
					results = append(results, map[string]interface{}{"locale": locale, "localized": true})
					continue OUT
				}
			}
			results = append(results, map[string]interface{}{"locale": locale, "localized": false})
		}
		return results
	})

	// Roles
	role := res.Config.Permission.Role
	if _, ok := role.Get("locale_admin"); !ok {
		role.Register("locale_admin", func(req *http.Request, currentUser qor.CurrentUser) bool {
			currentLocale := getLocaleFromContext(&qor.Context{Request: req})
			for _, locale := range GetEditableLocales(req, currentUser) {
				if locale == currentLocale {
					return true
				}
			}
			return false
		})

		role.Register("locale_reader", func(req *http.Request, currentUser qor.CurrentUser) bool {
			currentLocale := getLocaleFromContext(&qor.Context{Request: req})
{'fraction_non_alphanumeric': 0.14135782223679896, 'fraction_numerical': 0.0026238110856018366, 'mean_word_length': 5.082446808510638, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2299031', 'n_tokens_mistral': 3143, 'n_tokens_neox': 2930, 'n_words': 578}