示例#1
0
// new site init data
func NewSiteInitData(engine *xorm.Engine) {
	// default user
	user := &model.User{
		Name:      "admin",
		Nick:      "admin",
		Email:     "*****@*****.**",
		Url:       "#",
		AvatarUrl: utils.GravatarLink("*****@*****.**"),
		Profile:   "this is an administrator",
		Role:      model.USER_ROLE_ADMIN,
		Status:    model.USER_STATUS_ACTIVE,
	}
	user.Salt = utils.Md5String("123456789")[8:24]
	user.Password = utils.Sha256String("123456789" + user.Salt)
	if _, err := engine.Insert(user); err != nil {
		log.Error("NewSite | %s", err.Error())
		return
	}

	// default article
	article := &model.Article{
		Title:         "Welcome to Purine",
		Link:          "welcome-to-purine",
		Preview:       blogPreview,
		Body:          blogContent,
		TagString:     "blog",
		Hits:          1,
		Comments:      0,
		Status:        model.ARTICLE_STATUS_PUBLISH,
		CommentStatus: model.ARTICLE_COMMENT_OPEN,
		AuthorId:      user.Id,
	}
	if _, err := engine.Insert(article); err != nil {
		log.Error("NewSite | %s", err.Error())
		return
	}

	// default settings
	settings := make([]interface{}, 0)
	settings = append(settings, &model.Setting{"title", "Purine", 0})
	settings = append(settings, &model.Setting{"subtitle", "a simple blog engine", 0})
	settings = append(settings, &model.Setting{"desc", "a simple blog engine by golang", 0})
	settings = append(settings, &model.Setting{"keyword", "purine,blog,golang", 0})
	settings = append(settings, &model.Setting{"theme", "default", 0})
	settings = append(settings, &model.Setting{"baseurl", "http://localhost:9999/", 0})
	settings = append(settings, &model.Setting{"media_imageext", ".jpg,.jpeg,.png,.gif", 0})
	settings = append(settings, &model.Setting{"media_fileext", ".txt,.zip,.doc,.xls,.ppt,.pdf", 0})
	settings = append(settings, &model.Setting{"media_nameformat", ":hash", 0})
	settings = append(settings, &model.Setting{"media_maxsize", strconv.Itoa(2 * 1024 * 1024), 0})
	if _, err := engine.Insert(settings...); err != nil {
		log.Error("NewSite | %s", err.Error())
		return
	}
}
示例#2
0
// save a comment,
// always insert new
func SaveComment(c *Comment) error {
	if _, err := vars.Db.Insert(c); err != nil {
		log.Error("Db|SaveComment|%s", err.Error())
		return err
	}
	return nil
}
示例#3
0
// save setting with key, value and owner id
func SaveSetting(key, value string, uid int64) error {
	if _, err := vars.Db.Where("name = ?", key).Delete(new(Setting)); err != nil {
		log.Error("Db|SaveSetting|%s,%s,%d|%s", key, value, uid, err.Error())
		return err
	}
	s := &Setting{
		Name:   key,
		Value:  value,
		UserId: uid,
	}
	if _, err := vars.Db.Insert(s); err != nil {
		log.Error("Db|SaveSetting|%s,%s,%d|%s", key, value, uid, err.Error())
		return err
	}
	return nil
}
示例#4
0
// get current theme
func GetCurrentTheme() (*Theme, error) {
	themeSetting, err := GetSettings("theme")
	if err != nil {
		return nil, err
	}

	t := new(Theme)
	t.Directory = themeSetting["theme"]
	t.IsCurrent = true
	tomlFile := path.Join("static", t.Directory, "theme.toml")
	if com.IsFile(tomlFile) {
		if _, err := toml.DecodeFile(tomlFile, t); err != nil {
			log.Error("Db|GetCurrentTheme|%s|%s", tomlFile, err.Error())
			return nil, err
		}
	}
	// fill data
	if t.Name == "" {
		t.Name = t.Directory
	}
	if t.Version == "" {
		t.Version = "0.0"
	}

	return t, nil
}
示例#5
0
func saveTags(id int64, tagStr string) error {
	// delete old tags
	if _, err := vars.Db.Where("article_id = ?", id).Delete(new(Tag)); err != nil {
		log.Error("Db|SaveTags|%d,%s|%s", id, tagStr, err.Error())
		return err
	}
	// save new tags
	tags := strings.Split(strings.Replace(tagStr, ",", ",", -1), ",")
	for _, t := range tags {
		if _, err := vars.Db.Insert(&Tag{ArticleId: id, Tag: t}); err != nil {
			log.Error("Db|SaveTags|%d,%s|%s", id, t, err.Error())
			return err
		}
	}
	return nil
}
示例#6
0
// check email's approved comment count
func CountApprovedCommentsByEmail(email string) int64 {
	c, err := vars.Db.Where("status = ? AND email = ?", COMMENT_STATUS_APPROVED, email).Count(new(Comment))
	if err != nil {
		log.Error("Db|CountApprovedCommentsByEmail|%s|%s", email, err.Error())
		return 0
	}
	return c
}
示例#7
0
文件: page.go 项目: insionng/purine
// save page.
// if page.Id, update page,
// or insert new page;
// return the saved page.
func SavePage(p *Page) (*Page, error) {
	if p.Id > 0 {
		if _, err := vars.Db.Where("id = ?", p.Id).
			Cols("title,link,update_time,body,topic,status,comment_status").
			Update(p); err != nil {
			log.Error("Db|SavePage|%d|%s", p.Id, err.Error())
			return nil, err
		}
	} else {
		if _, err := vars.Db.Insert(p); err != nil {
			log.Error("Db|SavePage|%d|%s", p.Id, err.Error())
			return nil, err
		}

	}
	return GetPageBy("id", p.Id)
}
示例#8
0
文件: user.go 项目: insionng/purine
// update user profile columns
func UpdateUser(u *User) error {
	if _, err := vars.Db.Cols("name,nick,email,url,profile,avatar_url").
		Where("id = ?", u.Id).Update(u); err != nil {
		log.Error("Db|UpdateUser|%d|%s", u.Id, err.Error())
		return err
	}
	return nil
}
示例#9
0
// change comment status
func ChangeCommentStatus(cid int64, status string) (*Comment, error) {
	c := &Comment{Status: status}
	if _, err := vars.Db.Id(cid).Cols("status").Update(c); err != nil {
		log.Error("Db|ChangeCommentStatus|%d,%s|%s", cid, status, err.Error())
		return nil, err
	}
	return GetCommentBy("id", cid)
}
示例#10
0
// get article by column and value
func GetArticleBy(col string, v interface{}) (*Article, error) {
	a := new(Article)
	if isIdColumn(col) {
		if _, err := vars.Db.Id(v).Get(a); err != nil {
			log.Error("Db|GetArticleBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	} else {
		if _, err := vars.Db.Where(col+" = ?", v).Get(a); err != nil {
			log.Error("Db|GetArticleBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	}
	if a.Id > 0 {
		return a, nil
	}
	return nil, nil
}
示例#11
0
// list general articles,
// contains publish and draft articles
func ListGeneralArticle(page, size int64, order string) ([]*Article, error) {
	articles := make([]*Article, 0)
	if err := vars.Db.Where("status != ?", ARTICLE_STATUS_DELETE).
		Limit(int(size), int((page-1)*size)).OrderBy(order).Find(&articles); err != nil {
		log.Error("Db|ListGeneralArticle|%d,%d|%s|%s", page, size, order, err.Error())
		return nil, err
	}
	return articles, nil
}
示例#12
0
// remove article by id
func RemoveArticle(id int64) error {
	a := new(Article)
	a.Status = ARTICLE_STATUS_DELETE
	if _, err := vars.Db.Where("id = ?", id).Cols("status").Update(a); err != nil {
		log.Error("Db|RemoveArticle|%d|%s", id, err.Error())
		return err
	}
	return nil
}
示例#13
0
// list articles with one status
func ListStatusArticle(status string, page, size int64, order string) ([]*Article, error) {
	articles := make([]*Article, 0)
	if err := vars.Db.Where("status = ?", status).
		Limit(int(size), int((page-1)*size)).OrderBy(order).Find(&articles); err != nil {
		log.Error("Db|ListStatusArticle|%s|%d,%d|%s|%s", status, page, size, order, err.Error())
		return nil, err
	}
	return articles, nil
}
示例#14
0
文件: page.go 项目: insionng/purine
// get page by column and value
func GetPageBy(col string, v interface{}) (*Page, error) {
	p := new(Page)
	if isIdColumn(col) {
		if _, err := vars.Db.Id(v).Get(p); err != nil {
			log.Error("Db|GetPageBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	} else {
		if _, err := vars.Db.Where(col+" = ?", v).Get(p); err != nil {
			log.Error("Db|GetPageBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	}
	if p.Id > 0 {
		return p, nil
	}
	return nil, nil
}
示例#15
0
// get a comment by column and value
func GetCommentBy(col string, v interface{}) (*Comment, error) {
	c := new(Comment)
	if isIdColumn(col) {
		if _, err := vars.Db.Id(v).Get(c); err != nil {
			log.Error("Db|GetCommentBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	} else {
		if _, err := vars.Db.Where(col+" = ?", v).Get(c); err != nil {
			log.Error("Db|GetCommentBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	}
	if c.Id > 0 {
		return c, nil
	}
	return nil, nil
}
示例#16
0
文件: user.go 项目: insionng/purine
// get user by column and value
func GetUserBy(col string, v interface{}) (*User, error) {
	u := new(User)
	if isIdColumn(col) {
		if _, err := vars.Db.Id(v).Get(u); err != nil {
			log.Error("Db|GetUserBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	} else {
		if _, err := vars.Db.Where(col+" = ?", v).Get(u); err != nil {
			log.Error("Db|GetUserBy|%s,%v|%s", col, v, err.Error())
			return nil, err
		}
	}
	if u.Id == 0 {
		return nil, nil
	}
	return u, nil
}
示例#17
0
// list comments in specific status
func ListStatusComments(status string, page, size int64, order string) ([]*Comment, error) {
	comments := make([]*Comment, 0)
	if err := vars.Db.Where("status = ?", status).OrderBy(order).
		Limit(int(size), int((page-1)*size)).Find(&comments); err != nil {
		log.Error("Db|ListStatusComments|%s|%d,%d|%s|%s", status, page, size, order, err.Error())
		return nil, err
	}
	return comments, nil
}
示例#18
0
文件: user.go 项目: insionng/purine
// update user password with user id and new password
func UpdatePassword(id int64, newPassword string) error {
	u := new(User)
	u.Salt = utils.Md5String(newPassword)[8:24]
	u.Password = utils.Sha256String(newPassword + u.Salt)
	if _, err := vars.Db.Cols("password,salt").Where("id = ?", id).Update(u); err != nil {
		log.Error("Db|UpdatePassword|%d|%s", id, err.Error())
		return err
	}
	return nil
}
示例#19
0
// list all comments
func ListAllComments(page, size int64, order string) ([]*Comment, error) {
	comments := make([]*Comment, 0)
	if err := vars.Db.OrderBy(order).
		Where("status != ?", COMMENT_STATUS_DELETED).
		Limit(int(size), int((page-1)*size)).Find(&comments); err != nil {
		log.Error("Db|ListAllComments|%s|%d,%d|%s|%s", "all", page, size, order, err.Error())
		return nil, err
	}
	return comments, nil
}
示例#20
0
// list comments by status in article
func ListStatusCommentsInArticle(status string, aid, page, size int64, order string) ([]*Comment, error) {
	comments := make([]*Comment, 0)
	if err := vars.Db.
		Where("status = ? AND `from` = ? AND `from_id` = ?", status, COMMENT_FROM_ARTICLE, aid).
		OrderBy(order).
		Limit(int(size), int((page-1)*size)).Find(&comments); err != nil {
		log.Error("Db|ListStatusCommentsInArticle|%s|%d,%d|%s|%s", status, page, size, order, err.Error())
		return nil, err
	}
	return comments, nil
}
示例#21
0
文件: media.go 项目: insionng/purine
// list media files
func ListMedia(page, size int64) ([]*Media, error) {
	media := make([]*Media, 0)
	if err := vars.Db.
		Limit(int(size), int((page-1)*size)).
		OrderBy("id DESC").
		Find(&media); err != nil {
		log.Error("Db|ListMedia|%d,%d|%s", page, size, err.Error())
		return nil, err
	}
	return media, nil
}
示例#22
0
文件: user.go 项目: insionng/purine
// create new token with user id and expiration duration
func CreateToken(user, expire int64) (*Token, error) {
	t := &Token{
		UserId:     user,
		ExpireTime: time.Now().Unix() + expire,
	}
	t.Token = utils.Md5String(fmt.Sprintf("%d,%d", t.UserId, t.ExpireTime))
	if _, err := vars.Db.Insert(t); err != nil {
		log.Error("Db|CreateToken|%v|%s", t, err.Error())
		return nil, err
	}
	return t, nil
}
示例#23
0
// new site data
func NewSiteData(ctx *cli.Context) {
	sqliteVersion, _, _ := sqlite3.Version()
	log.Info("NewSite | %-8s | %s | %s", "SQLite", sqliteVersion, vars.DATA_FILE)

	engine, err := xorm.NewEngine("sqlite3", vars.DATA_FILE)
	if err != nil {
		log.Error("NewSite | %s", err.Error())
		return
	}
	engine.SetLogger(nil) // close logger

	if err = engine.Sync2(new(model.User),
		new(model.Token),
		new(model.Article),
		new(model.Page),
		new(model.Tag),
		new(model.Setting),
		new(model.Media),
		new(model.Comment)); err != nil {
		log.Error("NewSite | %s", err.Error())
		return
	}

	log.Info("NewSite | %-8s | SyncDb | %s,%s,%s,%s,%s,%s,%s,%s", "SQLite",
		reflect.TypeOf(new(model.User)).String(),
		reflect.TypeOf(new(model.Token)).String(),
		reflect.TypeOf(new(model.Article)).String(),
		reflect.TypeOf(new(model.Page)).String(),
		reflect.TypeOf(new(model.Tag)).String(),
		reflect.TypeOf(new(model.Setting)).String(),
		reflect.TypeOf(new(model.Media)).String(),
		reflect.TypeOf(new(model.Comment)).String(),
	)

	// site init data
	NewSiteInitData(engine)

	log.Info("NewSite | %-8s | Success", "SQLite")
	engine.Close()
}
示例#24
0
// new site
func NewSite(ctx *cli.Context) {
	config := model.NewConfig()

	// encode config
	if err := model.WriteConfig(config, vars.CONFIG_FILE); err != nil {
		log.Error("NewSite | %s", err.Error())
		return
	}

	log.Info("NewSite | %-8s | %s", "Init", vars.CONFIG_FILE)
	log.Info("NewSite | %-8s | %s", "Version", config.Version)
	log.Info("NewSite | %-8s | %s:%s", "Server", config.Server.Host, config.Server.Port)
}
示例#25
0
// upgrade action
func UpgradeAction(cfg *model.Config) {
	t := time.Now()
	log.Debug("Upgrade | %-8s | %s(%s) -> %s(%s)", "Upgrade", cfg.Version, cfg.Date, vars.VERSION, vars.VERSION_DATE)

	opt := &PrepareOption{true, true, false}
	pre, err := Prepare(opt)
	if err != nil {
		log.Error("Upgrade | %-8s | %s", "Prepare", err.Error())
		return
	}
	log.Info("Upgrade | %-8s | %s", "Prepare", opt.String())

	oldVersion, _ := strconv.Atoi(pre.Config.Date)
	scriptIndex := []int{}
	for vr, _ := range upg.Script {
		if vr > oldVersion {
			scriptIndex = append(scriptIndex, vr)
		}
	}
	sort.Sort(sort.IntSlice(scriptIndex))

	for _, cv := range scriptIndex {
		log.Debug("Upgrade | %-8s | %d ", "Process", cv)
		if err := upg.Script[cv](); err != nil {
			log.Error("Upgrade | %-8s | %s", "Process", err.Error())
			return
		}
	}

	pre.Config.Version = vars.VERSION
	pre.Config.Date = vars.VERSION_DATE
	if err := model.WriteConfig(pre.Config, vars.CONFIG_FILE); err != nil {
		log.Error("Upgrade | %-8s | SyncFail", "Config")
		return
	}

	log.Info("Upgrade | %-8s | Sync | %s", "Config", vars.CONFIG_FILE)
	log.Info("Upgrade | %-8s | %.1fms", "Done", time.Since(t).Seconds()*1000)
}
示例#26
0
// get settings by keys
func GetSettings(keys ...string) (map[string]string, error) {
	str := `"` + strings.Join(keys, `","`) + `"`
	settings := make([]*Setting, 0)
	if err := vars.Db.Where("name IN (" + str + ")").Find(&settings); err != nil {
		log.Error("Db|GetSettings|%v|%s", keys, err.Error())
		return nil, err
	}
	m := make(map[string]string)
	for _, s := range settings {
		m[s.Name] = s.Value
	}
	return m, nil
}
示例#27
0
// save article.
// if Article.Id, update article,
// or insert new article;
// return the saved article.
func SaveArticle(a *Article) (*Article, error) {
	if a.Id > 0 {
		if _, err := vars.Db.Where("id = ?", a.Id).
			Cols("title,link,update_time,preview,body,topic,tag_string,status,comment_status").
			Update(a); err != nil {
			log.Error("Db|SaveArticle|%d|%s", a.Id, err.Error())
			return nil, err
		}
	} else {
		if _, err := vars.Db.Insert(a); err != nil {
			log.Error("Db|SaveArticle|%d|%s", a.Id, err.Error())
			return nil, err
		}

	}
	if a.TagString != "" {
		if err := saveTags(a.Id, a.TagString); err != nil {
			return nil, err
		}
	}
	return GetArticleBy("id", a.Id)
}
示例#28
0
// get themes in diretory
func GetThemes() ([]*Theme, error) {
	themeSetting, err := GetSettings("theme")
	if err != nil {
		return nil, err
	}
	dirs, err := ioutil.ReadDir("static")
	if err != nil {
		return nil, err
	}
	themes := make([]*Theme, 0)
	for _, d := range dirs {
		if !d.IsDir() {
			continue
		}
		// ignore admin and upload directory
		if d.Name() == "admin" || d.Name() == "upload" {
			continue
		}

		t := new(Theme)
		t.Directory = d.Name()
		// read theme file
		tomlFile := path.Join("static", d.Name(), "theme.toml")
		if com.IsFile(tomlFile) {
			if _, err := toml.DecodeFile(tomlFile, t); err != nil {
				log.Error("Db|GetThemes|%s|%s", tomlFile, err.Error())
				return nil, err
			}
		} else {
			continue
		}

		// fill data
		if t.Name == "" {
			t.Name = d.Name()
		}
		if t.Version == "" {
			t.Version = "0.0"
		}

		// is current
		if t.Directory == themeSetting["theme"] {
			t.IsCurrent = true
		}

		themes = append(themes, t)
	}
	return themes, nil
}
示例#29
0
文件: pack.go 项目: insionng/purine
// pack static files to source
func PackSrc(ctx *cli.Context) {
	t := time.Now()
	log.Info("Pack | %-8s", "Source")

	file, err := packSrcZip()
	if err != nil {
		log.Error("Pack | %-8s | %s", "ZipSrc", err.Error())
		return
	}

	bytes, err := ioutil.ReadFile(file)
	if err != nil {
		log.Error("Pack | %-8s | %s", "ZipSrc", err.Error())
		return
	}
	zipWriter, err := os.OpenFile("cmd/asset.go", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
	if err != nil {
		log.Error("Pack | %-8s | %s", "ZipSrc", err.Error())
		return
	}
	header := `package cmd
const zipBytes="`
	zipWriter.Write([]byte(header))
	encoder := base64.NewEncoder(base64.StdEncoding, zipWriter)
	encoder.Write(bytes)
	encoder.Close()
	zipWriter.Write([]byte(`"`))
	zipWriter.Sync()
	zipWriter.Close()
	if err = os.Remove(file); err != nil {
		log.Error("Pack | %-8s | %s", "ZipSrc", err.Error())
		return
	}
	log.Info("Pack | %-8s | %s", "ZipSrc", utils.FriendBytesSize(int64(len(bytes))))
	log.Info("Pack | %-8s | %.1fms", "ZipSrc", time.Since(t).Seconds()*1000)
}
示例#30
0
文件: user.go 项目: insionng/purine
// get valid token.
// it checks expiration.
func GetValidToken(token string) (*Token, error) {
	t := new(Token)
	if _, err := vars.Db.Where("token = ?", token).Get(t); err != nil {
		log.Error("Db|GetValidToken|%s|%s", token, err.Error())
		return nil, err
	}
	// wrong token
	if t.Token != token {
		return nil, nil
	}
	// expired
	if time.Now().Unix() > t.ExpireTime {
		return nil, nil
	}
	return t, nil
}