Files
leanote/app/service/ConfigService.go
lealife f270ade8d7 1.4
2015-11-28 17:58:42 +08:00

616 lines
17 KiB
Go

package service
import (
"fmt"
"github.com/leanote/leanote/app/db"
"github.com/leanote/leanote/app/info"
. "github.com/leanote/leanote/app/lea"
"github.com/revel/revel"
"gopkg.in/mgo.v2/bson"
"os"
"os/exec"
"strconv"
"strings"
"time"
)
// 配置服务
// 只是全局的, 用户的配置没有
type ConfigService struct {
adminUserId string
siteUrl string
adminUsername string
// 全局的
GlobalAllConfigs map[string]interface{}
GlobalStringConfigs map[string]string
GlobalArrayConfigs map[string][]string
GlobalMapConfigs map[string]map[string]string
GlobalArrMapConfigs map[string][]map[string]string
}
// appStart时 将全局的配置从数据库中得到作为全局
func (this *ConfigService) InitGlobalConfigs() bool {
this.GlobalAllConfigs = map[string]interface{}{}
this.GlobalStringConfigs = map[string]string{}
this.GlobalArrayConfigs = map[string][]string{}
this.GlobalMapConfigs = map[string]map[string]string{}
this.GlobalArrMapConfigs = map[string][]map[string]string{}
this.adminUsername, _ = revel.Config.String("adminUsername")
if this.adminUsername == "" {
this.adminUsername = "admin"
}
this.siteUrl, _ = revel.Config.String("site.url")
userInfo := userService.GetUserInfoByAny(this.adminUsername)
if userInfo.UserId == "" {
return false
}
this.adminUserId = userInfo.UserId.Hex()
configs := []info.Config{}
db.ListByQ(db.Configs, bson.M{"UserId": userInfo.UserId}, &configs)
for _, config := range configs {
if config.IsArr {
this.GlobalArrayConfigs[config.Key] = config.ValueArr
this.GlobalAllConfigs[config.Key] = config.ValueArr
} else if config.IsMap {
this.GlobalMapConfigs[config.Key] = config.ValueMap
this.GlobalAllConfigs[config.Key] = config.ValueMap
} else if config.IsArrMap {
this.GlobalArrMapConfigs[config.Key] = config.ValueArrMap
this.GlobalAllConfigs[config.Key] = config.ValueArrMap
} else {
this.GlobalStringConfigs[config.Key] = config.ValueStr
this.GlobalAllConfigs[config.Key] = config.ValueStr
}
}
return true
}
func (this *ConfigService) GetSiteUrl() string {
return this.siteUrl
}
func (this *ConfigService) GetAdminUsername() string {
return this.adminUsername
}
func (this *ConfigService) GetAdminUserId() string {
return this.adminUserId
}
// 通用方法
func (this *ConfigService) updateGlobalConfig(userId, key string, value interface{}, isArr, isMap, isArrMap bool) bool {
// 判断是否存在
if _, ok := this.GlobalAllConfigs[key]; !ok {
// 需要添加
config := info.Config{ConfigId: bson.NewObjectId(),
UserId: bson.ObjectIdHex(userId),
Key: key,
IsArr: isArr,
IsMap: isMap,
IsArrMap: isArrMap,
UpdatedTime: time.Now(),
}
if isArr {
v, _ := value.([]string)
config.ValueArr = v
this.GlobalArrayConfigs[key] = v
} else if isMap {
v, _ := value.(map[string]string)
config.ValueMap = v
this.GlobalMapConfigs[key] = v
} else if isArrMap {
v, _ := value.([]map[string]string)
config.ValueArrMap = v
this.GlobalArrMapConfigs[key] = v
} else {
v, _ := value.(string)
config.ValueStr = v
this.GlobalStringConfigs[key] = v
}
return db.Insert(db.Configs, config)
} else {
i := bson.M{"UpdatedTime": time.Now()}
this.GlobalAllConfigs[key] = value
if isArr {
v, _ := value.([]string)
i["ValueArr"] = v
this.GlobalArrayConfigs[key] = v
} else if isMap {
v, _ := value.(map[string]string)
i["ValueMap"] = v
this.GlobalMapConfigs[key] = v
} else if isArrMap {
v, _ := value.([]map[string]string)
i["ValueArrMap"] = v
this.GlobalArrMapConfigs[key] = v
} else {
v, _ := value.(string)
i["ValueStr"] = v
this.GlobalStringConfigs[key] = v
}
return db.UpdateByQMap(db.Configs, bson.M{"UserId": bson.ObjectIdHex(userId), "Key": key}, i)
}
}
// 更新用户配置
func (this *ConfigService) UpdateGlobalStringConfig(userId, key string, value string) bool {
return this.updateGlobalConfig(userId, key, value, false, false, false)
}
func (this *ConfigService) UpdateGlobalArrayConfig(userId, key string, value []string) bool {
return this.updateGlobalConfig(userId, key, value, true, false, false)
}
func (this *ConfigService) UpdateGlobalMapConfig(userId, key string, value map[string]string) bool {
return this.updateGlobalConfig(userId, key, value, false, true, false)
}
func (this *ConfigService) UpdateGlobalArrMapConfig(userId, key string, value []map[string]string) bool {
return this.updateGlobalConfig(userId, key, value, false, false, true)
}
// 获取全局配置, 博客平台使用
func (this *ConfigService) GetGlobalStringConfig(key string) string {
return this.GlobalStringConfigs[key]
}
func (this *ConfigService) GetGlobalArrayConfig(key string) []string {
arr := this.GlobalArrayConfigs[key]
if arr == nil {
return []string{}
}
return arr
}
func (this *ConfigService) GetGlobalMapConfig(key string) map[string]string {
m := this.GlobalMapConfigs[key]
if m == nil {
return map[string]string{}
}
return m
}
func (this *ConfigService) GetGlobalArrMapConfig(key string) []map[string]string {
m := this.GlobalArrMapConfigs[key]
if m == nil {
return []map[string]string{}
}
return m
}
func (this *ConfigService) IsOpenRegister() bool {
return this.GetGlobalStringConfig("openRegister") != ""
}
//-------
// 修改共享笔记的配置
func (this *ConfigService) UpdateShareNoteConfig(registerSharedUserId string,
registerSharedNotebookPerms, registerSharedNotePerms []int,
registerSharedNotebookIds, registerSharedNoteIds, registerCopyNoteIds []string) (ok bool, msg string) {
defer func() {
if err := recover(); err != nil {
ok = false
msg = fmt.Sprint(err)
}
}()
// 用户是否存在?
if registerSharedUserId == "" {
ok = true
msg = "share userId is blank, So it share nothing to register"
this.UpdateGlobalStringConfig(this.adminUserId, "registerSharedUserId", "")
return
} else {
user := userService.GetUserInfo(registerSharedUserId)
if user.UserId == "" {
ok = false
msg = "no such user: " + registerSharedUserId
return
} else {
this.UpdateGlobalStringConfig(this.adminUserId, "registerSharedUserId", registerSharedUserId)
}
}
notebooks := []map[string]string{}
// 共享笔记本
if len(registerSharedNotebookIds) > 0 {
for i := 0; i < len(registerSharedNotebookIds); i++ {
// 判断笔记本是否存在
notebookId := registerSharedNotebookIds[i]
if notebookId == "" {
continue
}
notebook := notebookService.GetNotebook(notebookId, registerSharedUserId)
if notebook.NotebookId == "" {
ok = false
msg = "The user has no such notebook: " + notebookId
return
} else {
perm := "0"
if registerSharedNotebookPerms[i] == 1 {
perm = "1"
}
notebooks = append(notebooks, map[string]string{"notebookId": notebookId, "perm": perm})
}
}
}
this.UpdateGlobalArrMapConfig(this.adminUserId, "registerSharedNotebooks", notebooks)
notes := []map[string]string{}
// 共享笔记
if len(registerSharedNoteIds) > 0 {
for i := 0; i < len(registerSharedNoteIds); i++ {
// 判断笔记本是否存在
noteId := registerSharedNoteIds[i]
if noteId == "" {
continue
}
note := noteService.GetNote(noteId, registerSharedUserId)
if note.NoteId == "" {
ok = false
msg = "The user has no such note: " + noteId
return
} else {
perm := "0"
if registerSharedNotePerms[i] == 1 {
perm = "1"
}
notes = append(notes, map[string]string{"noteId": noteId, "perm": perm})
}
}
}
this.UpdateGlobalArrMapConfig(this.adminUserId, "registerSharedNotes", notes)
// 复制
noteIds := []string{}
if len(registerCopyNoteIds) > 0 {
for i := 0; i < len(registerCopyNoteIds); i++ {
// 判断笔记本是否存在
noteId := registerCopyNoteIds[i]
if noteId == "" {
continue
}
note := noteService.GetNote(noteId, registerSharedUserId)
if note.NoteId == "" {
ok = false
msg = "The user has no such note: " + noteId
return
} else {
noteIds = append(noteIds, noteId)
}
}
}
this.UpdateGlobalArrayConfig(this.adminUserId, "registerCopyNoteIds", noteIds)
ok = true
return
}
// 添加备份
func (this *ConfigService) AddBackup(path, remark string) bool {
backups := this.GetGlobalArrMapConfig("backups") // [{}, {}]
n := time.Now().Unix()
nstr := fmt.Sprintf("%v", n)
backups = append(backups, map[string]string{"createdTime": nstr, "path": path, "remark": remark})
return this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
}
func (this *ConfigService) getBackupDirname() string {
n := time.Now()
y, m, d := n.Date()
return strconv.Itoa(y) + "_" + m.String() + "_" + strconv.Itoa(d) + "_" + fmt.Sprintf("%v", n.Unix())
}
func (this *ConfigService) Backup(remark string) (ok bool, msg string) {
binPath := configService.GetGlobalStringConfig("mongodumpPath")
config := revel.Config
dbname, _ := config.String("db.dbname")
host, _ := revel.Config.String("db.host")
port, _ := revel.Config.String("db.port")
username, _ := revel.Config.String("db.username")
password, _ := revel.Config.String("db.password")
// mongodump -h localhost -d leanote -o /root/mongodb_backup/leanote-9-22/ -u leanote -p nKFAkxKnWkEQy8Vv2LlM
binPath = binPath + " -h " + host + " -d " + dbname + " --port " + port
if username != "" {
binPath += " -u " + username + " -p " + password
}
// 保存的路径
dir := revel.BasePath + "/mongodb_backup/" + this.getBackupDirname()
binPath += " -o " + dir
err := os.MkdirAll(dir, 0755)
if err != nil {
ok = false
msg = fmt.Sprintf("%v", err)
return
}
cmd := exec.Command("/bin/sh", "-c", binPath)
Log(binPath)
b, err := cmd.Output()
if err != nil {
msg = fmt.Sprintf("%v", err)
ok = false
Log("error:......")
Log(string(b))
return
}
ok = configService.AddBackup(dir, remark)
return ok, msg
}
// 还原
func (this *ConfigService) Restore(createdTime string) (ok bool, msg string) {
backups := this.GetGlobalArrMapConfig("backups") // [{}, {}]
var i int
var backup map[string]string
for i, backup = range backups {
if backup["createdTime"] == createdTime {
break
}
}
if i == len(backups) {
return false, "Backup Not Found"
}
// 先备份当前
ok, msg = this.Backup("Auto backup when restore from " + backup["createdTime"])
if !ok {
return
}
// mongorestore -h localhost -d leanote --directoryperdb /home/user1/gopackage/src/github.com/leanote/leanote/mongodb_backup/leanote_install_data/
binPath := configService.GetGlobalStringConfig("mongorestorePath")
config := revel.Config
dbname, _ := config.String("db.dbname")
host, _ := revel.Config.String("db.host")
port, _ := revel.Config.String("db.port")
username, _ := revel.Config.String("db.username")
password, _ := revel.Config.String("db.password")
// mongorestore -h localhost -d leanote -o /root/mongodb_backup/leanote-9-22/ -u leanote -p nKFAkxKnWkEQy8Vv2LlM
binPath = binPath + " --drop -h " + host + " -d " + dbname + " --port " + port
if username != "" {
binPath += " -u " + username + " -p " + password
}
path := backup["path"] + "/" + dbname
// 判断路径是否存在
if !IsDirExists(path) {
return false, path + " Is Not Exists"
}
binPath += " " + path
cmd := exec.Command("/bin/sh", "-c", binPath)
Log(binPath)
b, err := cmd.Output()
if err != nil {
msg = fmt.Sprintf("%v", err)
ok = false
Log("error:......")
Log(string(b))
return
}
return true, ""
}
func (this *ConfigService) DeleteBackup(createdTime string) (bool, string) {
backups := this.GetGlobalArrMapConfig("backups") // [{}, {}]
var i int
var backup map[string]string
for i, backup = range backups {
if backup["createdTime"] == createdTime {
break
}
}
if i == len(backups) {
return false, "Backup Not Found"
}
// 删除文件夹之
err := os.RemoveAll(backups[i]["path"])
if err != nil {
return false, fmt.Sprintf("%v", err)
}
// 删除之
backups = append(backups[0:i], backups[i+1:]...)
ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
return ok, ""
}
func (this *ConfigService) UpdateBackupRemark(createdTime, remark string) (bool, string) {
backups := this.GetGlobalArrMapConfig("backups") // [{}, {}]
var i int
var backup map[string]string
for i, backup = range backups {
if backup["createdTime"] == createdTime {
break
}
}
if i == len(backups) {
return false, "Backup Not Found"
}
backup["remark"] = remark
ok := this.UpdateGlobalArrMapConfig(this.adminUserId, "backups", backups)
return ok, ""
}
// 得到备份
func (this *ConfigService) GetBackup(createdTime string) (map[string]string, bool) {
backups := this.GetGlobalArrMapConfig("backups") // [{}, {}]
var i int
var backup map[string]string
for i, backup = range backups {
if backup["createdTime"] == createdTime {
break
}
}
if i == len(backups) {
return map[string]string{}, false
}
return backup, true
}
//--------------
// sub domain
var defaultDomain string
var schema = "http://"
var port string
func init() {
revel.OnAppStart(func() {
/*
不用配置的, 因为最终通过命令可以改, 而且有的使用nginx代理
port = strconv.Itoa(revel.HttpPort)
if port != "80" {
port = ":" + port
} else {
port = "";
}
*/
siteUrl, _ := revel.Config.String("site.url") // 已包含:9000, http, 去掉成 leanote.com
if strings.HasPrefix(siteUrl, "http://") {
defaultDomain = siteUrl[len("http://"):]
} else if strings.HasPrefix(siteUrl, "https://") {
defaultDomain = siteUrl[len("https://"):]
schema = "https://"
}
// port localhost:9000
ports := strings.Split(defaultDomain, ":")
if len(ports) == 2 {
port = ports[1]
}
if port == "80" {
port = ""
} else {
port = ":" + port
}
})
}
func (this *ConfigService) GetSchema() string {
return schema
}
// 默认
func (this *ConfigService) GetDefaultDomain() string {
return defaultDomain
}
// 包含http://
func (this *ConfigService) GetDefaultUrl() string {
return schema + defaultDomain
}
// note
func (this *ConfigService) GetNoteDomain() string {
subDomain := this.GetGlobalStringConfig("noteSubDomain")
if subDomain != "" {
return subDomain + port
}
return this.GetDefaultDomain() + "/note"
}
func (this *ConfigService) GetNoteUrl() string {
return schema + this.GetNoteDomain()
}
// blog
func (this *ConfigService) GetBlogDomain() string {
subDomain := this.GetGlobalStringConfig("blogSubDomain")
if subDomain != "" {
return subDomain + port
}
return this.GetDefaultDomain() + "/blog"
}
func (this *ConfigService) GetBlogUrl() string {
return schema + this.GetBlogDomain()
}
// lea
func (this *ConfigService) GetLeaDomain() string {
subDomain := this.GetGlobalStringConfig("leaSubDomain")
if subDomain != "" {
return subDomain + port
}
return this.GetDefaultDomain() + "/lea"
}
func (this *ConfigService) GetLeaUrl() string {
return schema + this.GetLeaDomain()
}
func (this *ConfigService) GetUserUrl(domain string) string {
return schema + domain + port
}
func (this *ConfigService) GetUserSubUrl(subDomain string) string {
return schema + subDomain + "." + this.GetDefaultDomain()
}
// 是否允许自定义域名
func (this *ConfigService) AllowCustomDomain() bool {
return configService.GetGlobalStringConfig("allowCustomDomain") != ""
}
// 是否是好的自定义域名
func (this *ConfigService) IsGoodCustomDomain(domain string) bool {
blacks := this.GetGlobalArrayConfig("blackCustomDomains")
for _, black := range blacks {
if strings.Contains(domain, black) {
return false
}
}
return true
}
func (this *ConfigService) IsGoodSubDomain(domain string) bool {
blacks := this.GetGlobalArrayConfig("blackSubDomains")
LogJ(blacks)
for _, black := range blacks {
if domain == black {
return false
}
}
return true
}
// 上传大小
func (this *ConfigService) GetUploadSize(key string) float64 {
f, _ := strconv.ParseFloat(this.GetGlobalStringConfig(key), 64)
return f
}
func (this *ConfigService) GetInt64(key string) int64 {
f, _ := strconv.ParseInt(this.GetGlobalStringConfig(key), 10, 64)
return f
}
func (this *ConfigService) GetInt32(key string) int32 {
f, _ := strconv.ParseInt(this.GetGlobalStringConfig(key), 10, 32)
return int32(f)
}
func (this *ConfigService) GetUploadSizeLimit() map[string]float64 {
return map[string]float64{
"uploadImageSize": this.GetUploadSize("uploadImageSize"),
"uploadBlogLogoSize": this.GetUploadSize("uploadBlogLogoSize"),
"uploadAttachSize": this.GetUploadSize("uploadAttachSize"),
"uploadAvatarSize": this.GetUploadSize("uploadAvatarSize"),
}
}
// 为用户得到全局的配置
// NoteController调用
func (this *ConfigService) GetGlobalConfigForUser() map[string]interface{} {
uploadSizeConfigs := this.GetUploadSizeLimit()
config := map[string]interface{}{}
for k, v := range uploadSizeConfigs {
config[k] = v
}
return config
}
// 主页是否是管理员的博客页
func (this *ConfigService) HomePageIsAdminsBlog() bool {
return this.GetGlobalStringConfig("homePage") == ""
}
func (this *ConfigService) GetVersion() string {
return "1.4"
}