Ejemplo n.º 1
0
// Startup brings the manager to a running state.
func Startup(sessionID string) error {
	// If the system has already been started ignore the call.
	if singleton.sessions != nil {
		return nil
	}

	log.Started(sessionID, "Startup")

	// Pull in the configuration.
	var config mongoConfiguration
	if err := envconfig.Process("mgo", &config); err != nil {
		log.CompletedError(err, sessionID, "Startup")
		return err
	}

	// Create the Mongo Manager.
	singleton = mongoManager{
		sessions: make(map[string]mongoSession),
	}

	// Create the strong session.
	if err := CreateSession(sessionID, "strong", MasterSession, config.Url); err != nil {
		log.CompletedError(err, sessionID, "Startup")
		return err
	}

	// Create the monotonic session.
	if err := CreateSession(sessionID, "monotonic", MonotonicSession, config.Url); err != nil {
		log.CompletedError(err, sessionID, "Startup")
		return err
	}

	log.Completed(sessionID, "Startup")
	return nil
}
Ejemplo n.º 2
0
func FindUserByName(service *services.Service, userName string) (*userModel.UserInfo, error) {
	log.Startedf(service.UserID, "FindUserByName", "userName[%s]", userName)
	var userInfo userModel.UserInfo
	f := func(collection *mgo.Collection) error {
		queryMap := bson.M{
			"$or": []bson.M{
				bson.M{"user_name": userName},
				bson.M{"user_email": userName},
				bson.M{"user_mobile": userName},
			},
		}
		log.Trace(service.UserID, "FindUserByName", "MGO : db.user_infos.find(%s).limit(1)", mongo.ToString(queryMap))
		return collection.Find(queryMap).One(&userInfo)
	}

	if err := service.DBAction(Config.Database, "user_infos", f); err != nil {
		if err != mgo.ErrNotFound {
			log.CompletedError(err, service.UserID, "FindUserByName")
			return nil, err
		}
	}

	log.Completedf(service.UserID, "FindUserByName", "userInfo%+v", &userInfo)
	return &userInfo, nil
}
Ejemplo n.º 3
0
func init() {
	// Pull in the configuration
	err := envconfig.Process("buoy", &Config)
	if err != nil {
		tracelog.CompletedError(err, helper.MAIN_GO_ROUTINE, "Init")
	}
}
Ejemplo n.º 4
0
// searchDirectory recurses through the specified directory looking
// for i18n folders. If found it will load the translations files
func searchDirectory(directory string, pwd string) {
	// Read the directory
	fileInfos, err := ioutil.ReadDir(directory)
	if err != nil {
		tracelog.CompletedError(err, "localize", "searchDirectory")
		return
	}

	// Look for i18n folders
	for _, fileInfo := range fileInfos {
		if fileInfo.IsDir() == true {
			fullPath := fmt.Sprintf("%s/%s", directory, fileInfo.Name())

			// If this directory is the current directory, ignore it
			if fullPath == pwd {
				continue
			}

			// Is this an i18n folder
			if fileInfo.Name() == "i18n" {
				loadTranslationFiles(fullPath)
				continue
			}

			// Look for more sub-directories
			searchDirectory(fullPath, pwd)
			continue
		}
	}
}
Ejemplo n.º 5
0
func main() {
	tracelog.Start(tracelog.LevelTrace)

	// Init mongo
	tracelog.Started("main", "Initializing Mongo")
	err := mongo.Startup(helper.MainGoRoutine)
	if err != nil {
		tracelog.CompletedError(err, helper.MainGoRoutine, "initApp")
		os.Exit(1)
	}

	// Load message strings
	localize.Init("en-US")

	SessionConfig, err := session.GetSessionConfig("session")

	tracelog.Trace("main", "SessionConfig", "Session : On[%v]", SessionConfig.On)
	tracelog.Trace("main", "SessionConfig", "Session : On[%v]", SessionConfig.Provider)
	tracelog.Trace("main", "SessionConfig", "Session : On[%v]", SessionConfig.SavePath)

	beego.SessionOn = SessionConfig.On
	beego.SessionProvider = SessionConfig.Provider
	beego.SessionSavePath = SessionConfig.SavePath

	beego.Run()

	tracelog.Completed(helper.MainGoRoutine, "Website Shutdown")
	tracelog.Stop()
}
Ejemplo n.º 6
0
// FindStation retrieves the specified station
func FindStation(service *services.Service, stationId string) (buoyStation *buoyModels.BuoyStation, err error) {
	defer helper.CatchPanic(&err, service.UserId, "FindStation")

	tracelog.Started(service.UserId, "FindStation")

	queryMap := bson.M{"station_id": stationId}

	buoyStation = &buoyModels.BuoyStation{}
	err = service.DBAction(Config.Database, "buoy_stations",
		func(collection *mgo.Collection) error {
			tracelog.Trace(service.UserId, "FindStation", "Query : %s", mongo.ToString(queryMap))
			return collection.Find(queryMap).One(buoyStation)
		})

	if err != nil {
		if strings.Contains(err.Error(), "not found") == false {
			tracelog.CompletedError(err, service.UserId, "FindStation")
			return buoyStation, err
		}

		err = nil
	}

	tracelog.Completed(service.UserId, "FindStation")
	return buoyStation, err
}
Ejemplo n.º 7
0
// MustLoadDB loads the database
func MustLoadDB() {
	handle.once.Do(func() {
		// Get database name
		database := ConfigEntry("Database")
		conn, err := sql.Open(ConfigEntry("Driver"), ConfigEntry("Username")+":"+ConfigEntry("Password")+"@/"+database+"?parseTime=true")
		if err != nil {
			tracelog.CompletedError(err, "MustLoadDB", "sql.Open")
			panic(err.Error())
		}

		handle.value = conn
		err = handle.value.Ping()
		if err != nil {
			tracelog.CompletedError(err, "MustLoadDB", "handle.value.Ping")
			panic(err.Error())
		}
	})
}
Ejemplo n.º 8
0
// UserAuth checks if a session exists
func UserAuth(store *sessions.CookieStore) gin.HandlerFunc {
	return func(c *gin.Context) {
		session := c.MustGet("session").(*sessions.Session)
		if session.Values["uid"] == nil {
			tracelog.CompletedError(errSession, "UserAuth", "Checking of session uid value")
			c.Error(errSession, "No session")
			c.AbortWithStatus(401)
		}
	}
}
Ejemplo n.º 9
0
// Startup brings the manager to a running state.
func Startup(sessionID string) error {
	// If the system has already been started ignore the call.
	if singleton.sessions != nil {
		return nil
	}

	log.Started(sessionID, "Startup")

	// Pull in the configuration.
	var config mongoConfiguration
	if err := envconfig.Process("mgo", &config); err != nil {
		log.CompletedError(err, sessionID, "Startup")
		return err
	}

	// Create the Mongo Manager.
	singleton = mongoManager{
		sessions: make(map[string]mongoSession),
	}

	// Log the mongodb connection straps.
	log.Trace(sessionID, "Startup", "MongoDB : Hosts[%s]", config.Hosts)
	log.Trace(sessionID, "Startup", "MongoDB : Database[%s]", config.Database)
	log.Trace(sessionID, "Startup", "MongoDB : Username[%s]", config.UserName)

	hosts := strings.Split(config.Hosts, ",")

	// Create the strong session.
	if err := CreateSession(sessionID, "strong", MasterSession, hosts, config.Database, config.UserName, config.Password); err != nil {
		log.CompletedError(err, sessionID, "Startup")
		return err
	}

	// Create the monotonic session.
	if err := CreateSession(sessionID, "monotonic", MonotonicSession, hosts, config.Database, config.UserName, config.Password); err != nil {
		log.CompletedError(err, sessionID, "Startup")
		return err
	}

	log.Completed(sessionID, "Startup")
	return nil
}
Ejemplo n.º 10
0
func (sc *Song) Index(c *gin.Context) {
	songs, err := sc.SM.GetAll()
	if err != nil {
		tracelog.CompletedError(err, "Song", "Index")
		c.JSON(500, gin.H{"message": "Something went wrong.", "status": 500})

		return
	}

	c.JSON(200, gin.H{"songs": songs})
}
Ejemplo n.º 11
0
// ConfirmDelete deletes the user
func (uc *User) ConfirmDelete(c *gin.Context) {
	// Delete user
	err := uc.UM.Delete(c.Params.ByName("nonce"))
	if err != nil {
		tracelog.CompletedError(err, "NewUser", "uc.UM.Delete")
		c.JSON(500, gin.H{"message": "Something went wrong.", "status": 500})
		return
	}

	c.JSON(200, gin.H{"message": "User deleted successfully.", "status": 200})
}
Ejemplo n.º 12
0
// Execute the MongoDB literal function.
func Execute(sessionID string, mongoSession *mgo.Session, databaseName string, collectionName string, dbCall DBCall) error {
	log.Startedf(sessionID, "Execute", "Database[%s] Collection[%s]", databaseName, collectionName)

	// Capture the specified collection.
	collection := GetCollection(mongoSession, databaseName, collectionName)
	if collection == nil {
		err := fmt.Errorf("Collection %s does not exist", collectionName)
		log.CompletedError(err, sessionID, "Execute")
		return err
	}

	// Execute the MongoDB call.
	err := dbCall(collection)
	if err != nil {
		log.CompletedError(err, sessionID, "Execute")
		return err
	}

	log.Completed(sessionID, "Execute")
	return nil
}
Ejemplo n.º 13
0
// Register registers the user
func (uc *User) Register(c *gin.Context) {
	var r Register
	// Bind params
	c.Bind(&r)

	// Set user data
	uc.UM.UserData.Email = r.Email
	uc.UM.UserData.Username = r.Username
	uc.UM.UserData.FirstName = r.FirstName
	uc.UM.UserData.LastName = r.LastName
	uc.UM.UserData.Hash = utils.ComputeHmac256(r.Password, utils.ConfigEntry("Salt"))
	uc.UM.UserData.AccessLevel = 10 // Figure out how to set this properly
	uc.UM.UserData.Joined = time.Now().Local()

	// Create user
	id, err := uc.UM.Create()
	if err != nil {
		tracelog.CompletedError(err, "NewUser", "uc.UM.Save")
		c.JSON(500, gin.H{"message": "Something went wrong.", "status": 500})
		return
	}

	if id == 0 {
		c.JSON(409, gin.H{"message": "Duplicate entry.", "status": 409})
		return
	}

	// Set user ID to last inserted ID
	uc.UM.UserData.Id = strconv.FormatInt(id, 10)

	// Set session
	err = uc.setSession(c)
	if err != nil {
		tracelog.CompletedError(err, "NewUser", "uc.setSession")
		c.JSON(500, gin.H{"message": "Something went wrong.", "status": 500})
		return
	}

	c.JSON(200, gin.H{"message": "Registered successfully.", "status": 200})
}
Ejemplo n.º 14
0
// Session attaches session to gin context
func Session(store *sessions.CookieStore) gin.HandlerFunc {
	return func(c *gin.Context) {
		session, err := store.Get(c.Request, utils.ConfigEntry("SessionName"))
		if err != nil {
			tracelog.CompletedError(err, "Session", "Getting the session")
			c.Error(err, "Failed to create session")
			c.AbortWithStatus(500)
		}

		c.Set("session", session)
		defer context.Clear(c.Request)
	}
}
Ejemplo n.º 15
0
// Execute the MongoDB literal function
func Execute(sessionId string, mongoSession *mgo.Session, databaseName string, collectionName string, mongoCall MongoCall) (err error) {
	tracelog.Startedf(sessionId, "Execute", "Database[%s] Collection[%s]", databaseName, collectionName)

	// Capture the specified collection
	collection, err := GetCollection(mongoSession, databaseName, collectionName)
	if err != nil {

		tracelog.CompletedError(err, sessionId, "Execute")
		return err
	}

	// Execute the mongo call
	err = mongoCall(collection)
	if err != nil {
		tracelog.CompletedError(err, sessionId, "Execute")
		return err
	}

	tracelog.Completed(sessionId, "Execute")

	return err
}
Ejemplo n.º 16
0
// CreateSession creates a connection pool for use
func CreateSession(sessionId string, mode string, sessionName string, hosts []string, databaseName string, username string, password string) (err error) {
	defer helper.CatchPanic(nil, sessionId, "CreateSession")

	tracelog.Startedf(sessionId, "CreateSession", "Mode[%s] SessionName[%s] Hosts[%s] DatabaseName[%s] Username[%s]", mode, sessionName, hosts, databaseName, username)

	// Create the database object
	mongoSession := &mongoSession{
		mongoDBDialInfo: &mgo.DialInfo{
			Addrs:    hosts,
			Timeout:  60 * time.Second,
			Database: databaseName,
			Username: username,
			Password: password,
		},
	}

	// Establish the master session
	mongoSession.mongoSession, err = mgo.DialWithInfo(mongoSession.mongoDBDialInfo)
	if err != nil {
		tracelog.CompletedError(err, sessionId, "CreateSession")
		return err
	}

	switch mode {
	case "strong":
		// Reads and writes will always be made to the master server using a
		// unique connection so that reads and writes are fully consistent,
		// ordered, and observing the most up-to-date data.
		// http://godoc.org/labix.org/v2/mgo#Session.SetMode
		mongoSession.mongoSession.SetMode(mgo.Strong, true)
		break

	case "monotonic":
		// Reads may not be entirely up-to-date, but they will always see the
		// history of changes moving forward, the data read will be consistent
		// across sequential queries in the same session, and modifications made
		// within the session will be observed in following queries (read-your-writes).
		// http://godoc.org/labix.org/v2/mgo#Session.SetMode
		mongoSession.mongoSession.SetMode(mgo.Monotonic, true)
	}

	// Have the session check for errors
	// http://godoc.org/labix.org/v2/mgo#Session.SetSafe
	mongoSession.mongoSession.SetSafe(&mgo.Safe{})

	// Add the database to the map
	singleton.sessions[sessionName] = mongoSession

	tracelog.Completed(sessionId, "CreateSession")
	return err
}
Ejemplo n.º 17
0
// Create creates a nonce
func (nc *Nonce) Create(c *gin.Context) {
	// Get session
	session := c.MustGet("session").(*sessions.Session)

	nonce, err := nc.NM.Create(session.Values["uid"].(string))
	if err != nil {
		tracelog.CompletedError(err, "Nonce", "Create")
		c.JSON(500, gin.H{"message": "Something went wrong.", "status": 500})

		return
	}

	c.JSON(200, gin.H{"nonce": nonce})
}
Ejemplo n.º 18
0
// init initializes all required packages and systems
func init() {
	//	log.Start(log.LEVEL_TRACE)

	// Init mongo
	log.Started("main", "Initializing Mongo")
	err := mongo.Startup(helper.MainGoRoutine)
	if err != nil {
		log.CompletedError(err, helper.MainGoRoutine, "initTesting")
		return
	}

	// Load message strings
	localize.Init("en-US")
}
Ejemplo n.º 19
0
// MustLoadConfig loads the configs and assign it to configMap
func MustLoadConfig() {
	ci.once.Do(func() {
		// Get app mode -- test/development/production
		mode := EnvConfigEntry("Mode")
		fmt.Println(mode)
		// Find the location of the config.json file
		configFilePath, err := filepath.Abs("app/configs/" + mode + ".json")

		// Open the config.json file
		file, err := os.Open(configFilePath)
		if err != nil {
			tracelog.CompletedError(err, "MustLoadConfig", "os.Open")
			panic(err.Error())
		}
		defer file.Close()

		// Read the config file
		decoder := json.NewDecoder(file)
		c := &config{}
		err = decoder.Decode(&c)
		if err != nil {
			tracelog.CompletedError(err, "MustLoadConfig", "decoder.Decode")
			panic(err.Error())
		}

		// Create a configMap object
		ci.value = configMap{ConfigMap: make(map[string]string)}

		// Assign config field:value pairs to ConfigMap
		v := reflect.ValueOf(c).Elem()
		vType := v.Type()
		for i := 0; i < v.NumField(); i++ {
			f := v.Field(i)
			ci.value.ConfigMap[vType.Field(i).Name] = f.Interface().(string)
		}
	})
}
Ejemplo n.º 20
0
func UserLogup(service *services.Service, userInfo userModel.UserInfo) (*userModel.UserInfo, error) {
	log.Startedf(service.UserID, "UserLogup", "user[%s]", userInfo.UserName)
	f := func(collection *mgo.Collection) error {
		log.Trace(service.UserID, "UserLogup", "MGO : db.user_infos.insert(%s)", mongo.ToString(userInfo))
		return collection.Insert(&userInfo)
	}
	if err := service.DBAction(Config.Database, "user_infos", f); err != nil {
		if err != mgo.ErrNotFound {
			log.CompletedError(err, service.UserID, "UserLogup")
			return nil, err
		}
	}
	log.Completedf(service.UserID, "UserLogup", "userInfo%+v", &userInfo)
	return &userInfo, nil
}
Ejemplo n.º 21
0
// Login logs the user in
func (uc *User) Login(c *gin.Context) {
	var g Login
	// Bind params
	c.Bind(&g)

	// Check if user exists and get User instance if it does
	user, err := uc.UM.User("email", g.Username)
	if err != nil {
		// Mybe the user provided the username instead of email
		user, err = uc.UM.User("username", g.Username)
		if user != nil {
			tracelog.CompletedError(err, "NewUser", "uc.UM.NewUser")
			c.JSON(401, gin.H{"message": "Invalid Username.", "status": 401})
			return
		}
	}

	// Compare hashes
	hash := utils.ComputeHmac256(g.Password, utils.ConfigEntry("Salt"))
	if hash != user.UserData.Hash {
		tracelog.CompletedError(err, "NewUser", "Hashes comparison")
		c.JSON(401, gin.H{"message": "Invalid password.", "status": 401})
		return
	}

	// Set session
	uc.UM.UserData = user.UserData
	err = uc.setSession(c)
	if err != nil {
		tracelog.CompletedError(err, "NewUser", "uc.setSession")
		c.JSON(500, gin.H{"message": "Something went wrong.", "status": 500})
		return
	}

	c.JSON(200, gin.H{"message": "Logged in successfully.", "status": 200})
}
Ejemplo n.º 22
0
// Nonce verifies the nonce attached to a request
func Nonce(nm *models.Nonce) gin.HandlerFunc {
	return func(c *gin.Context) {
		var n N
		// Bind params
		c.Bind(&n)

		var err error
		var id string
		if n.Nonce == "" {
			val, ok := c.Request.URL.Query()["nonce"]
			if ok && val[0] != "" {
				id, err = nm.Verify(val[0])
			} else {
				tracelog.CompletedError(errNonce, "Nonce", "Empty or no nonce sent")
				c.Error(errNonce, "Empty or no nonce sent")
				c.AbortWithStatus(401)
			}
		} else {
			id, err = nm.Verify(n.Nonce)
		}

		if err != nil {
			tracelog.CompletedError(err, "Nonce", "nm.Verify")
			c.Error(err, "Invalid nonce sent")
			c.AbortWithStatus(401)
		}

		// Delete nonce once verified
		err = nm.Delete(id)
		if err != nil {
			tracelog.CompletedError(err, "Nonce", "nm.Delete")
			c.Error(err, "Something went wrong")
			c.AbortWithStatus(500)
		}
	}
}
Ejemplo n.º 23
0
func main() {

	tracelog.Start(tracelog.LevelTrace)
	err := mongo.Startup(helper.MainGoRoutine)
	if err != nil {
		tracelog.CompletedError(err, helper.MainGoRoutine, "initApp")
		os.Exit(1)
	} else {
		fmt.Println("mongodb启动正常")
	}
	beego.Run()

	tracelog.Completed(helper.MainGoRoutine, "Website Shutdown")
	tracelog.Stop()
}
Ejemplo n.º 24
0
func SaveFile(service *services.Service, fileInfo fileModels.FileInfo) (*fileModels.FileInfo, error) {
	log.Startedf(service.UserID, "SaveFile", "FileHash[%s]", fileInfo.FileHash)

	f := func(collection *mgo.Collection) error {
		log.Trace(service.UserID, "SaveFile", "MGO : db.file_infos.insert(%s)", mongo.ToString(fileInfo))
		return collection.Insert(&fileInfo)
	}
	if err := service.DBAction(Config.Database, "file_infos", f); err != nil {
		if err != mgo.ErrNotFound {
			log.CompletedError(err, service.UserID, "SaveFile")
			return nil, err
		}
	}

	log.Completedf(service.UserID, "SaveFile", "fileInfo%+v", &fileInfo)
	return &fileInfo, nil
}
Ejemplo n.º 25
0
// CloneSession makes a clone of the specified session for client use.
func CloneSession(sessionID string, useSession string) (*mgo.Session, error) {
	log.Startedf(sessionID, "CloneSession", "UseSession[%s]", useSession)

	// Find the session object.
	session := singleton.sessions[useSession]

	if session.mongoSession == nil {
		err := fmt.Errorf("Unable To Locate Session %s", useSession)
		log.CompletedError(err, sessionID, "CloneSession")
		return nil, err
	}

	// Clone the master session.
	mongoSession := session.mongoSession.Clone()

	log.Completed(sessionID, "CloneSession")
	return mongoSession, nil
}
Ejemplo n.º 26
0
func main() {
	tracelog.Start(tracelog.LEVEL_TRACE)

	// Init mongo
	tracelog.Started("main", "Initializing Mongo")
	err := mongo.Startup(helper.MAIN_GO_ROUTINE)
	if err != nil {
		tracelog.CompletedError(err, helper.MAIN_GO_ROUTINE, "initApp")
		os.Exit(1)
	}

	// Load message strings
	localize.Init("en-US")

	beego.Run()

	tracelog.Completed(helper.MAIN_GO_ROUTINE, "Website Shutdown")
	tracelog.Stop()
}
Ejemplo n.º 27
0
func main() {
	tracelog.Start(tracelog.LevelTrace)

	// Init mongo
	tracelog.Started("main", "Initializing Mongo")
	err := mongo.Startup(helper.MainGoRoutine)
	if err != nil {
		tracelog.CompletedError(err, helper.MainGoRoutine, "initApp")
		os.Exit(1)
	}

	// Load message strings
	localize.Init("en-US")

	beego.Run()

	tracelog.Completed(helper.MainGoRoutine, "Website Shutdown")
	tracelog.Stop()
}
Ejemplo n.º 28
0
// FindRegion retrieves the stations for the specified region
func FindRegion(service *services.Service, region string) ([]buoyModels.BuoyStation, error) {
	log.Startedf(service.UserID, "FindRegion", "region[%s]", region)

	var buoyStations []buoyModels.BuoyStation
	f := func(collection *mgo.Collection) error {
		queryMap := bson.M{"region": region}

		log.Trace(service.UserID, "FindRegion", "Query : db.buoy_stations.find(%s)", mongo.ToString(queryMap))
		return collection.Find(queryMap).All(&buoyStations)
	}

	if err := service.DBAction(Config.Database, "buoy_stations", f); err != nil {
		log.CompletedError(err, service.UserID, "FindRegion")
		return nil, err
	}

	log.Completedf(service.UserID, "FindRegion", "buoyStations%+v", buoyStations)
	return buoyStations, nil
}
Ejemplo n.º 29
0
// CreateSession creates a connection pool for use.
func CreateSession(sessionID string, mode string, sessionName string, url string) error {
	log.Startedf(sessionID, "CreateSession", "Mode[%s] Url[%s]", mode, sessionName, url)

	// Create the database object
	mongoSession := mongoSession{}

	// Establish the master session.
	var err error
	mongoSession.mongoSession, err = mgo.Dial(url)
	if err != nil {
		log.CompletedError(err, sessionID, "CreateSession")
		return err
	}

	switch mode {
	case "strong":
		// Reads and writes will always be made to the master server using a
		// unique connection so that reads and writes are fully consistent,
		// ordered, and observing the most up-to-date data.
		// http://godoc.org/github.com/finapps/mgo#Session.SetMode
		mongoSession.mongoSession.SetMode(mgo.Strong, true)
		break

	case "monotonic":
		// Reads may not be entirely up-to-date, but they will always see the
		// history of changes moving forward, the data read will be consistent
		// across sequential queries in the same session, and modifications made
		// within the session will be observed in following queries (read-your-writes).
		// http://godoc.org/github.com/finapps/mgo#Session.SetMode
		mongoSession.mongoSession.SetMode(mgo.Monotonic, true)
	}

	// Have the session check for errors.
	// http://godoc.org/github.com/finapps/mgo#Session.SetSafe
	mongoSession.mongoSession.SetSafe(&mgo.Safe{})

	// Add the database to the map.
	singleton.sessions[sessionName] = mongoSession

	log.Completed(sessionID, "CreateSession")
	return nil
}
Ejemplo n.º 30
0
// loadTranslationFiles loads the found translation files into the i18n
// messaging system for use by the application
func loadTranslationFiles(directory string) {
	// Read the directory
	fileInfos, err := ioutil.ReadDir(directory)
	if err != nil {
		tracelog.CompletedError(err, "localize", "loadTranslationFiles")
		return
	}

	// Look for JSON files
	for _, fileInfo := range fileInfos {
		if path.Ext(fileInfo.Name()) != ".json" {
			continue
		}

		fileName := fmt.Sprintf("%s/%s", directory, fileInfo.Name())

		tracelog.Info("localize", "loadTranslationFiles", "Loading %s", fileName)
		i18n.MustLoadTranslationFile(fileName)
	}
}