// URL: /admin/ad/new // 添加广告 func adminNewAdHandler(handler *Handler) { defer dps.Persist() choices := []wtforms.Choice{ wtforms.Choice{"top0", "最顶部"}, wtforms.Choice{"top", "顶部"}, wtforms.Choice{"frontpage", "首页"}, wtforms.Choice{"content", "主题内"}, wtforms.Choice{"2cols", "2列宽度"}, wtforms.Choice{"3cols", "3列宽度"}, wtforms.Choice{"4cols", "4列宽度"}, } form := wtforms.NewForm( wtforms.NewSelectField("position", "位置", choices, "", wtforms.Required{}), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewTextField("index", "序号", "", wtforms.Required{}), wtforms.NewTextArea("code", "代码", "", wtforms.Required{}), ) if handler.Request.Method == "POST" { if !form.Validate(handler.Request) { handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) return } c := handler.DB.C(ADS) index, err := strconv.Atoi(form.Value("index")) if err != nil { form.AddError("index", "请输入正确的数字") handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) return } err = c.Insert(&AD{ Id_: bson.NewObjectId(), Position: form.Value("position"), Name: form.Value("name"), Code: form.Value("code"), Index: index, }) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/ads", http.StatusFound) return } handler.renderTemplate("ad/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) }
// URL: /article/new // 新建文章 func newArticleHandler(w http.ResponseWriter, r *http.Request) { var categories []ArticleCategory c := DB.C("articlecategories") c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewTextField("title", "标题", "", wtforms.Required{}), wtforms.NewTextField("original_source", "原始出处", "", wtforms.Required{}), wtforms.NewTextField("original_url", "原始链接", "", wtforms.URL{}), wtforms.NewSelectField("category", "分类", choices, ""), ) if r.Method == "POST" && form.Validate(r) { user, _ := currentUser(r) c = DB.C("contents") id_ := bson.NewObjectId() html := form.Value("html") html = strings.Replace(html, "<pre>", `<pre class="prettyprint linenums">`, -1) categoryId := bson.ObjectIdHex(form.Value("category")) err := c.Insert(&Article{ Content: Content{ Id_: id_, Type: TypeArticle, Title: form.Value("title"), CreatedBy: user.Id_, CreatedAt: time.Now(), }, Id_: id_, CategoryId: categoryId, OriginalSource: form.Value("original_source"), OriginalUrl: form.Value("original_url"), }) if err != nil { fmt.Println("newArticleHandler:", err.Error()) return } http.Redirect(w, r, "/a/"+id_.Hex(), http.StatusFound) return } renderTemplate(w, r, "article/form.html", map[string]interface{}{ "form": form, "title": "新建", "action": "/article/new", "active": "article", }) }
// URL: /admin/package_category/{id}/edit // 修改包分类 func adminEditPackageCategoryHandler(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] c := DB.C(PACKAGE_CATEGORIES) var category PackageCategory c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&category) form := wtforms.NewForm( wtforms.NewTextField("id", "ID", category.Id, wtforms.Required{}), wtforms.NewTextField("name", "名称", category.Name, wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "package_category/form.html", ADMIN, map[string]interface{}{"form": form}) return } c.Update(bson.M{"_id": bson.ObjectIdHex(id)}, bson.M{"$set": bson.M{ "id": form.Value("id"), "name": form.Value("name"), }}) http.Redirect(w, r, "/admin/package_categories", http.StatusFound) } renderTemplate(w, r, "package_category/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": false, }) }
// URL /profile // 用户设置页面,显示用户设置,用户头像,密码修改 func profileHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin?next=/profile", http.StatusFound) return } profileForm := wtforms.NewForm( wtforms.NewTextField("email", "电子邮件", user.Email, wtforms.Email{}), wtforms.NewTextField("website", "个人网站", user.Website), wtforms.NewTextField("location", "所在地", user.Location), wtforms.NewTextField("tagline", "签名", user.Tagline), wtforms.NewTextArea("bio", "个人简介", user.Bio), ) if r.Method == "POST" { if profileForm.Validate(r) { c := db.C("users") c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{"website": profileForm.Value("website"), "location": profileForm.Value("location"), "tagline": profileForm.Value("tagline"), "bio": profileForm.Value("bio"), }}) http.Redirect(w, r, "/profile", http.StatusFound) return } } renderTemplate(w, r, "account/profile.html", map[string]interface{}{"user": user, "profileForm": profileForm}) }
// URL: /admin/site_category/new // 新建站点分类 func adminNewSiteCategoryHandler(w http.ResponseWriter, r *http.Request) { form := wtforms.NewForm( wtforms.NewTextField("name", "名称", "", wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/new_site_category.html", map[string]interface{}{"adminNav": ADMIN_NAV, "form": form}) return } c := DB.C("sitecategories") var category SiteCategory err := c.Find(bson.M{"name": form.Value("name")}).One(&category) if err == nil { form.AddError("name", "该名称已经有了") renderTemplate(w, r, "admin/new_site_category.html", map[string]interface{}{"adminNav": ADMIN_NAV, "form": form}) return } err = c.Insert(&SiteCategory{ Id_: bson.NewObjectId(), Name: form.Value("name"), }) if err != nil { panic(err) } http.Redirect(w, r, "/admin/site_category/new", http.StatusFound) } renderTemplate(w, r, "admin/new_site_category.html", map[string]interface{}{"adminNav": ADMIN_NAV, "form": form}) }
// URL /profile // 用户设置页面,显示用户设置,用户头像,密码修改 func profileHandler(w http.ResponseWriter, r *http.Request) { user, _ := currentUser(r) profileForm := wtforms.NewForm( wtforms.NewTextField("email", "电子邮件", user.Email, wtforms.Email{}), wtforms.NewTextField("website", "个人网站", user.Website), wtforms.NewTextField("location", "所在地", user.Location), wtforms.NewTextField("tagline", "签名", user.Tagline), wtforms.NewTextArea("bio", "个人简介", user.Bio), wtforms.NewTextField("github_username", "GitHub用户名", user.GitHubUsername), wtforms.NewTextField("weibo", "新浪微博", user.Weibo), ) if r.Method == "POST" { if profileForm.Validate(r) { c := DB.C(USERS) c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{ "website": profileForm.Value("website"), "location": profileForm.Value("location"), "tagline": profileForm.Value("tagline"), "bio": profileForm.Value("bio"), "githubusername": profileForm.Value("github_username"), "weibo": profileForm.Value("weibo"), }}) http.Redirect(w, r, "/profile", http.StatusFound) return } } renderTemplate(w, r, "account/profile.html", BASE, map[string]interface{}{ "user": user, "profileForm": profileForm, "defaultAvatars": defaultAvatars, }) }
// URL: /login // 处理用户登录,如果登录成功,设置Cookie func loginHandler(handler Handler) { form := wtforms.NewForm( wtforms.NewTextField("username", "用户名", "", &wtforms.Required{}), wtforms.NewPasswordField("password", "密码", &wtforms.Required{}), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { if form.Value("username") == "sll" && form.Value("password") == "123456" { } else { form.AddError("password", "密码和用户名不匹配") renderHtml(handler, "login.html", map[string]interface{}{"form": form}) return } session, _ := store.Get(handler.Request, "user") session.Values["username"] = form.Value("username") session.Save(handler.Request, handler.ResponseWriter) http.Redirect(handler.ResponseWriter, handler.Request, "/", http.StatusFound) return } } renderHtml(handler, "login.html", map[string]interface{}{"form": form}) }
// URL: /admin/article_category/new // 新建文章分类 func adminNewArticleCategoryHandler(handler Handler) { form := wtforms.NewForm( wtforms.NewTextField("name", "名称", "", wtforms.Required{}), ) if handler.Request.Method == "POST" { if !form.Validate(handler.Request) { renderTemplate(handler, "article_category/new.html", ADMIN, map[string]interface{}{"form": form}) return } c := handler.DB.C(ARTICLE_CATEGORIES) var category ArticleCategory err := c.Find(bson.M{"name": form.Value("name")}).One(&category) if err == nil { form.AddError("name", "该名称已经有了") renderTemplate(handler, "article_category/new.html", ADMIN, map[string]interface{}{"form": form}) return } err = c.Insert(&ArticleCategory{ Id_: bson.NewObjectId(), Name: form.Value("name"), }) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/article_category/new", http.StatusFound) } renderTemplate(handler, "article_category/new.html", ADMIN, map[string]interface{}{"form": form}) }
// URL: /user_center/change_password // 修改密码 func changePasswordHandler(handler *Handler) { user, _ := currentUser(handler) form := wtforms.NewForm( wtforms.NewPasswordField("current_password", "当前密码", wtforms.Required{}), wtforms.NewPasswordField("new_password", "新密码", wtforms.Required{}), wtforms.NewPasswordField("confirm_password", "新密码确认", wtforms.Required{}), ) if handler.Request.Method == "POST" && form.Validate(handler.Request) { if form.Value("new_password") == form.Value("confirm_password") { if user.CheckPassword(form.Value("current_password")) { c := handler.DB.C(USERS) salt := strings.Replace(uuid.NewUUID().String(), "-", "", -1) c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{ "password": encryptPassword(form.Value("new_password"), salt), "salt": salt, }}) message(handler, "密码修改成功", `密码修改成功`, "success") return } else { form.AddError("current_password", "当前密码错误") } } else { form.AddError("confirm_password", "密码不匹配") } } handler.renderTemplate("user_center/change_password.html", BASE, map[string]interface{}{ "form": form, "active": "change_password", }) }
// URL: /change_password // 修改密码 func changePasswordHandler(handler Handler) { user, _ := currentUser(handler) form := wtforms.NewForm( wtforms.NewPasswordField("current_password", "当前密码", wtforms.Required{}), wtforms.NewPasswordField("new_password", "新密码", wtforms.Required{}), wtforms.NewPasswordField("confirm_password", "新密码确认", wtforms.Required{}), ) if handler.Request.Method == "POST" && form.Validate(handler.Request) { if form.Value("new_password") == form.Value("confirm_password") { currentPassword := encryptPassword(form.Value("current_password")) if currentPassword == user.Password { c := handler.DB.C(USERS) c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{"password": encryptPassword(form.Value("new_password"))}}) message(handler, "密码修改成功", `密码修改成功`, "success") return } else { form.AddError("current_password", "当前密码错误") } } else { form.AddError("confirm_password", "密码不匹配") } } renderTemplate(handler, "account/change_password.html", BASE, map[string]interface{}{"form": form}) }
// URL: /change_password // 修改密码 func changePasswordHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin?next=/change_password", http.StatusFound) return } form := wtforms.NewForm( wtforms.NewPasswordField("current_password", "当前密码", wtforms.Required{}), wtforms.NewPasswordField("new_password", "新密码", wtforms.Required{}), wtforms.NewPasswordField("confirm_password", "新密码确认", wtforms.Required{}), ) if r.Method == "POST" && form.Validate(r) { if form.Value("new_password") == form.Value("confirm_password") { currentPassword := encryptPassword(form.Value("current_password")) if currentPassword == user.Password { c := DB.C("users") c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{"password": encryptPassword(form.Value("new_password"))}}) message(w, r, "密码修改成功", `密码修改成功`, "success") return } else { form.AddError("current_password", "当前密码错误") } } else { form.AddError("confirm_password", "密码不匹配") } } renderTemplate(w, r, "account/change_password.html", map[string]interface{}{"form": form}) }
// wrapAuthHandler返回符合 go.auth包要求签名的函数. func wrapAuthHandler(handler *Handler) func(w http.ResponseWriter, r *http.Request, u auth.User) { return func(w http.ResponseWriter, r *http.Request, u auth.User) { c := handler.DB.C(USERS) user := User{} session, _ := store.Get(r, "user") c.Find(bson.M{"username": u.Id()}).One(&user) //关联github帐号,直接登录 if user.Provider == GITHUB_COM { session.Values["username"] = user.Username session.Save(r, w) http.Redirect(w, r, "/", http.StatusSeeOther) } form := wtforms.NewForm(wtforms.NewTextField("username", "用户名", "", wtforms.Required{}), wtforms.NewPasswordField("password", "密码", wtforms.Required{})) session.Values[GITHUB_EMAIL] = u.Email() session.Values[GITHUB_ID] = u.Id() session.Values[GITHUB_LINK] = u.Link() session.Values[GITHUB_NAME] = u.Name() session.Values[GITHUB_ORG] = u.Org() session.Values[GITHUB_PICTURE] = u.Picture() session.Values[GITHUB_PROVIDER] = u.Provider() session.Save(r, w) //关联已有帐号 if handler.Request.Method == "POST" { if form.Validate(handler.Request) { user := User{} err := c.Find(bson.M{"username": form.Value("username")}).One(&user) if err != nil { form.AddError("username", "该用户不存在") handler.renderTemplate("accoun/auth_login.html", BASE, map[string]interface{}{"form": form}) return } if !ComparePwd(form.Value("password"), user.Password) { form.AddError("password", "密码和用户名不匹配") handler.renderTemplate("account/auth_login.html", BASE, map[string]interface{}{"form": form, "captchaId": captcha.New()}) return } c.UpdateId(user.Id_, bson.M{"$set": bson.M{ "emal": session.Values[GITHUB_EMAIL], "accountref": session.Values[GITHUB_NAME], "username": session.Values[GITHUB_ID], "idref": session.Values[GITHUB_ID], "linkref": session.Values[GITHUB_LINK], "orgref": session.Values[GITHUB_ORG], "pictureref": session.Values[GITHUB_PICTURE], "provider": session.Values[GITHUB_PROVIDER], }}) deleteGithubValues(session) session.Values["username"] = u.Name() session.Save(r, w) http.Redirect(handler.ResponseWriter, handler.Request, "/", http.StatusFound) } } handler.renderTemplate("account/auth_login.html", BASE, map[string]interface{}{"form": form}) } }
// URL: /forgot_password // 忘记密码,输入用户名和邮箱,如果匹配,发出邮件 func forgotPasswordHandler(handler *Handler) { form := wtforms.NewForm( wtforms.NewTextField("username", "用户名", "", wtforms.Required{}), wtforms.NewTextField("email", "电子邮件", "", wtforms.Email{}), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { var user User c := handler.DB.C(USERS) err := c.Find(bson.M{"username": form.Value("username")}).One(&user) if err != nil { form.AddError("username", "没有该用户") } else if user.Email != form.Value("email") { form.AddError("username", "用户名和邮件不匹配") } else { message2 := `Hi %s,<br> 我们的系统收到一个请求,说你希望通过电子邮件重新设置你在 Golang中国 的密码。你可以点击下面的链接开始重设密码: <a href="%s/reset/%s">%s/reset/%s</a><br> 如果这个请求不是由你发起的,那没问题,你不用担心,你可以安全地忽略这封邮件。 如果你有任何疑问,可以回复<a href="mailto:[email protected]">[email protected]</a>向我提问。` code := strings.Replace(uuid.NewUUID().String(), "-", "", -1) c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{"resetcode": code}}) message2 = fmt.Sprintf(message2, user.Username, Config.Host, code, Config.Host, code) if Config.SendMailPath == "" { webhelpers.SendMail( "[Golang中国]重设密码", message2, Config.FromEmail, []string{user.Email}, webhelpers.SmtpConfig{ Username: Config.SmtpUsername, Password: Config.SmtpPassword, Host: Config.SmtpHost, Addr: Config.SmtpAddr, }, true, ) } else { webhelpers.SendMailExec( "[Golang中国]重设密码", message2, Config.FromEmail, []string{user.Email}, Config.SendMailPath, true, ) } message(handler, "通过电子邮件重设密码", "一封包含了重设密码指令的邮件已经发送到你的注册邮箱,按照邮件中的提示,即可重设你的密码。", "success") return } } } handler.renderTemplate("account/forgot_password.html", BASE, map[string]interface{}{"form": form}) }
// URL: /admin/node/new // 新建节点 func adminNewNodeHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin?next=/node/new", http.StatusFound) return } if !user.IsSuperuser { message(w, r, "没有权限", "你没有新建节点的权限", "error") return } form := wtforms.NewForm( wtforms.NewTextField("id", "ID", "", &wtforms.Required{}), wtforms.NewTextField("name", "名称", "", &wtforms.Required{}), wtforms.NewTextArea("description", "描述", "", &wtforms.Required{}), ) if r.Method == "POST" { if form.Validate(r) { c := db.C("nodes") node := Node{} err := c.Find(bson.M{"id": form.Value("id")}).One(&node) if err == nil { form.AddError("id", "该ID已经存在") renderTemplate(w, r, "node/new.html", map[string]interface{}{"form": form, "adminNav": ADMIN_NAV}) return } err = c.Find(bson.M{"name": form.Value("name")}).One(&node) if err == nil { form.AddError("name", "该名称已经存在") renderTemplate(w, r, "node/new.html", map[string]interface{}{"form": form, "adminNav": ADMIN_NAV}) return } Id_ := bson.NewObjectId() err = c.Insert(&Node{ Id_: Id_, Id: form.Value("id"), Name: form.Value("name"), Description: form.Value("description")}) if err != nil { panic(err) } http.Redirect(w, r, "/admin/node/new", http.StatusFound) } } renderTemplate(w, r, "node/new.html", map[string]interface{}{"form": form, "adminNav": ADMIN_NAV}) }
// URL: /package/new // 新建第三方包 func newPackageHandler(handler *Handler) { user, _ := currentUser(handler) var categories []PackageCategory c := handler.DB.C(PACKAGE_CATEGORIES) c.Find(nil).All(&categories) var choices []wtforms.Choice for _, category := range categories { choices = append(choices, wtforms.Choice{Value: category.Id_.Hex(), Label: category.Name}) } form := wtforms.NewForm( wtforms.NewHiddenField("html", ""), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewSelectField("category_id", "分类", choices, ""), wtforms.NewTextField("url", "网址", "", wtforms.Required{}, wtforms.URL{}), wtforms.NewTextArea("description", "描述", "", wtforms.Required{}), ) if handler.Request.Method == "POST" && form.Validate(handler.Request) { c = handler.DB.C(CONTENTS) id := bson.NewObjectId() categoryId := bson.ObjectIdHex(form.Value("category_id")) html := form.Value("html") html = strings.Replace(html, "<pre>", `<pre class="prettyprint linenums">`, -1) c.Insert(&Package{ Content: Content{ Id_: id, Type: TypePackage, Title: form.Value("name"), Markdown: form.Value("description"), Html: template.HTML(html), CreatedBy: user.Id_, CreatedAt: time.Now(), }, Id_: id, CategoryId: categoryId, Url: form.Value("url"), }) c = handler.DB.C(PACKAGE_CATEGORIES) // 增加数量 c.Update(bson.M{"_id": categoryId}, bson.M{"$inc": bson.M{"packagecount": 1}}) http.Redirect(handler.ResponseWriter, handler.Request, "/p/"+id.Hex(), http.StatusFound) return } handler.renderTemplate("package/form.html", BASE, map[string]interface{}{ "form": form, "title": "提交第三方包", "action": "/package/new", "active": "package", }) }
// ULR: /admin/link/new // 增加友链 func adminNewLinkHandler(handler *Handler) { defer dps.Persist() form := wtforms.NewForm( wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewTextField("url", "URL", "", wtforms.Required{}, wtforms.URL{}), wtforms.NewTextField("description", "描述", "", wtforms.Required{}), wtforms.NewTextField("logo", "Logo", ""), ) if handler.Request.Method == "POST" { if !form.Validate(handler.Request) { handler.renderTemplate("links/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) return } c := handler.DB.C(LINKS) var link Link err := c.Find(bson.M{"url": form.Value("url")}).One(&link) if err == nil { form.AddError("url", "该URL已经有了") handler.renderTemplate("links/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) return } err = c.Insert(&Link{ Id_: bson.NewObjectId(), Name: form.Value("name"), URL: form.Value("url"), Description: form.Value("description"), Logo: form.Value("logo"), IsOnHome: handler.Request.FormValue("is_on_home") == "on", IsOnBottom: handler.Request.FormValue("is_on_bottom") == "on", }) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/links", http.StatusFound) return } handler.renderTemplate("links/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) }
// URL: /admin/book/{id}/edit // 编辑图书 func editBookHandler(handler *Handler) { defer deferclient.Persist() bookId := mux.Vars(handler.Request)["id"] c := handler.DB.C(BOOKS) var book Book c.Find(bson.M{"_id": bson.ObjectIdHex(bookId)}).One(&book) form := wtforms.NewForm( wtforms.NewTextField("title", "书名", book.Title, wtforms.Required{}), wtforms.NewTextField("cover", "封面", book.Cover, wtforms.Required{}), wtforms.NewTextField("author", "作者", book.Author, wtforms.Required{}), wtforms.NewTextField("translator", "译者", book.Translator), wtforms.NewTextArea("introduction", "简介", book.Introduction), wtforms.NewTextField("pages", "页数", strconv.Itoa(book.Pages), wtforms.Required{}), wtforms.NewTextField("language", "语言", book.Language, wtforms.Required{}), wtforms.NewTextField("publisher", "出版社", book.Publisher), wtforms.NewTextField("publication_date", "出版年月日", book.PublicationDate), wtforms.NewTextField("isbn", "ISBN", book.ISBN), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { pages, _ := strconv.Atoi(form.Value("pages")) err := c.Update(bson.M{"_id": book.Id_}, bson.M{"$set": bson.M{ "title": form.Value("title"), "cover": form.Value("cover"), "author": form.Value("author"), "translator": form.Value("translator"), "introduction": form.Value("introduction"), "pages": pages, "language": form.Value("language"), "publisher": form.Value("publisher"), "publication_date": form.Value("publication_date"), "isbn": form.Value("isbn"), }}) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/books", http.StatusFound) return } } handler.renderTemplate("book/form.html", ADMIN, map[string]interface{}{ "book": book, "form": form, "isNew": false, }) }
// ULR: /admin/link_exchange/new // 增加友链 func adminNewLinkExchangeHandler(w http.ResponseWriter, r *http.Request) { form := wtforms.NewForm( wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewTextField("url", "URL", "", wtforms.Required{}, wtforms.URL{}), wtforms.NewTextField("description", "描述", "", wtforms.Required{}), wtforms.NewTextField("logo", "Logo", ""), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/link_exchange_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": true, }) return } c := DB.C("link_exchanges") var linkExchange LinkExchange err := c.Find(bson.M{"url": form.Value("url")}).One(&linkExchange) if err == nil { form.AddError("url", "该URL已经有了") renderTemplate(w, r, "admin/link_exchange_category.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": true, }) return } err = c.Insert(&LinkExchange{ Id_: bson.NewObjectId(), Name: form.Value("name"), URL: form.Value("url"), Description: form.Value("description"), Logo: form.Value("logo"), }) if err != nil { panic(err) } http.Redirect(w, r, "/admin/link_exchanges", http.StatusFound) return } renderTemplate(w, r, "admin/link_exchange_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": true, }) }
// URL: /signin // 处理用户登录,如果登录成功,设置Cookie func signinHandler(w http.ResponseWriter, r *http.Request) { next := r.FormValue("next") form := wtforms.NewForm( wtforms.NewHiddenField("next", next), wtforms.NewTextField("username", "用户名", "", &wtforms.Required{}), wtforms.NewPasswordField("password", "密码", &wtforms.Required{}), ) if r.Method == "POST" { if form.Validate(r) { c := DB.C("users") user := User{} err := c.Find(bson.M{"username": form.Value("username")}).One(&user) if err != nil { form.AddError("username", "该用户不存在") renderTemplate(w, r, "account/signin.html", map[string]interface{}{"form": form}) return } if !user.IsActive { form.AddError("username", "邮箱没有经过验证,如果没有收到邮件,请联系管理员") renderTemplate(w, r, "account/signin.html", map[string]interface{}{"form": form}) return } if user.Password != encryptPassword(form.Value("password")) { form.AddError("password", "密码和用户名不匹配") renderTemplate(w, r, "account/signin.html", map[string]interface{}{"form": form}) return } session, _ := store.Get(r, "user") session.Values["username"] = user.Username session.Save(r, w) if form.Value("next") == "" { http.Redirect(w, r, "/", http.StatusFound) } else { http.Redirect(w, r, next, http.StatusFound) } return } } renderTemplate(w, r, "account/signin.html", map[string]interface{}{"form": form}) }
// URL /user_center/edit_info // 修改用户资料 func editUserInfoHandler(handler *Handler) { user, _ := currentUser(handler) profileForm := wtforms.NewForm( wtforms.NewTextField("email", "电子邮件", user.Email, wtforms.Email{}), wtforms.NewTextField("website", "个人网站", user.Website), wtforms.NewTextField("location", "所在地", user.Location), wtforms.NewTextField("tagline", "签名", user.Tagline), wtforms.NewTextArea("bio", "个人简介", user.Bio), wtforms.NewTextField("github_username", "GitHub用户名", user.GitHubUsername), wtforms.NewTextField("weibo", "新浪微博", user.Weibo), ) if handler.Request.Method == "POST" { if profileForm.Validate(handler.Request) { c := handler.DB.C(USERS) // 检查邮箱 result := new(User) err := c.Find(bson.M{"email": profileForm.Value("email")}).One(result) if err == nil && result.Id_ != user.Id_ { profileForm.AddError("email", "电子邮件地址已经被使用") handler.renderTemplate("user_center/info_form.html", BASE, map[string]interface{}{ "user": user, "profileForm": profileForm, "active": "edit_info", }) return } c.Update(bson.M{"_id": user.Id_}, bson.M{"$set": bson.M{ "email": profileForm.Value("email"), "website": profileForm.Value("website"), "location": profileForm.Value("location"), "tagline": profileForm.Value("tagline"), "bio": profileForm.Value("bio"), "githubusername": profileForm.Value("github_username"), "weibo": profileForm.Value("weibo"), }}) handler.redirect("/user_center/edit_info", http.StatusFound) return } } handler.renderTemplate("user_center/info_form.html", BASE, map[string]interface{}{ "user": user, "profileForm": profileForm, "active": "edit_info", }) }
// URL: /admin/link/{linkId}/edit // 编辑友情链接 func adminEditLinkHandler(handler *Handler) { defer dps.Persist() linkId := mux.Vars(handler.Request)["linkId"] c := handler.DB.C(LINKS) var link Link c.Find(bson.M{"_id": bson.ObjectIdHex(linkId)}).One(&link) form := wtforms.NewForm( wtforms.NewTextField("name", "名称", link.Name, wtforms.Required{}), wtforms.NewTextField("url", "URL", link.URL, wtforms.Required{}, wtforms.URL{}), wtforms.NewTextField("description", "描述", link.Description, wtforms.Required{}), wtforms.NewTextField("logo", "Logo", link.Logo), ) if handler.Request.Method == "POST" { if !form.Validate(handler.Request) { handler.renderTemplate("links/form.html", ADMIN, map[string]interface{}{ "link": link, "form": form, "isNew": false, }) return } err := c.Update(bson.M{"_id": link.Id_}, bson.M{"$set": bson.M{ "name": form.Value("name"), "url": form.Value("url"), "description": form.Value("description"), "logo": form.Value("logo"), "is_on_home": handler.Request.FormValue("is_on_home") == "on", "is_on_bottom": handler.Request.FormValue("is_on_bottom") == "on", }}) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/links", http.StatusFound) return } handler.renderTemplate("links/form.html", ADMIN, map[string]interface{}{ "link": link, "form": form, "isNew": false, }) }
// URL: /admin/node/new // 新建节点 func adminNewNodeHandler(handler *Handler) { defer deferclient.Persist() form := wtforms.NewForm( wtforms.NewTextField("id", "ID", "", &wtforms.Required{}), wtforms.NewTextField("name", "名称", "", &wtforms.Required{}), wtforms.NewTextArea("description", "描述", "", &wtforms.Required{}), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { c := handler.DB.C(NODES) node := Node{} err := c.Find(bson.M{"id": form.Value("id")}).One(&node) if err == nil { form.AddError("id", "该ID已经存在") handler.renderTemplate("node/new.html", ADMIN, map[string]interface{}{"form": form}) return } err = c.Find(bson.M{"name": form.Value("name")}).One(&node) if err == nil { form.AddError("name", "该名称已经存在") handler.renderTemplate("node/new.html", ADMIN, map[string]interface{}{"form": form}) return } Id_ := bson.NewObjectId() err = c.Insert(&Node{ Id_: Id_, Id: form.Value("id"), Name: form.Value("name"), Description: form.Value("description")}) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/node/new", http.StatusFound) } } handler.renderTemplate("node/new.html", ADMIN, map[string]interface{}{"form": form}) }
// URL: /admin/package_category/new // 新建包分类 func adminNewPackageCategoryHandler(w http.ResponseWriter, r *http.Request) { user, ok := currentUser(r) if !ok { http.Redirect(w, r, "/signin?next=/admin/site_category/new", http.StatusFound) return } if !user.IsSuperuser { message(w, r, "没有权限", "你没有新建包分类的权限", "error") return } form := wtforms.NewForm( wtforms.NewTextField("id", "ID", "", wtforms.Required{}), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/new_package_category.html", map[string]interface{}{"adminNav": ADMIN_NAV, "form": form}) return } c := db.C("packagecategories") var category PackageCategory err := c.Find(bson.M{"name": form.Value("name")}).One(&category) if err == nil { form.AddError("name", "该名称已经有了") renderTemplate(w, r, "admin/new_package_category.html", map[string]interface{}{"adminNav": ADMIN_NAV, "form": form}) return } err = c.Insert(&PackageCategory{ Id_: bson.NewObjectId(), Id: form.Value("id"), Name: form.Value("name"), }) if err != nil { panic(err) } http.Redirect(w, r, "/admin/package_category/new", http.StatusFound) } renderTemplate(w, r, "admin/new_package_category.html", map[string]interface{}{"adminNav": ADMIN_NAV, "form": form}) }
// URL: /admin/ad/{id}/edit // 编辑广告 func adminEditAdHandler(w http.ResponseWriter, r *http.Request) { id := mux.Vars(r)["id"] c := DB.C("ads") var ad AD c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&ad) choices := []wtforms.Choice{ wtforms.Choice{"frongpage", "首页"}, wtforms.Choice{"3cols", "3列宽度"}, wtforms.Choice{"4cols", "4列宽度"}, } form := wtforms.NewForm( wtforms.NewSelectField("position", "位置", choices, ad.Position, wtforms.Required{}), wtforms.NewTextField("name", "名称", ad.Name, wtforms.Required{}), wtforms.NewTextArea("code", "代码", ad.Code, wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": false, }) return } err := c.Update(bson.M{"_id": ad.Id_}, bson.M{"$set": bson.M{ "position": form.Value("position"), "name": form.Value("name"), "code": form.Value("code"), }}) if err != nil { panic(err) } http.Redirect(w, r, "/admin/ads", http.StatusFound) return } renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": false, }) }
func newBookHandler(handler *Handler) { defer deferclient.Persist() form := wtforms.NewForm( wtforms.NewTextField("title", "书名", "", wtforms.Required{}), wtforms.NewTextField("cover", "封面", "", wtforms.Required{}), wtforms.NewTextField("author", "作者", "", wtforms.Required{}), wtforms.NewTextField("translator", "译者", ""), wtforms.NewTextArea("introduction", "简介", ""), wtforms.NewTextField("pages", "页数", "", wtforms.Required{}), wtforms.NewTextField("language", "语言", "", wtforms.Required{}), wtforms.NewTextField("publisher", "出版社", ""), wtforms.NewTextField("publication_date", "出版年月日", ""), wtforms.NewTextField("isbn", "ISBN", ""), ) if handler.Request.Method == "POST" { if form.Validate(handler.Request) { pages, _ := strconv.Atoi(form.Value("pages")) c := handler.DB.C(BOOKS) err := c.Insert(&Book{ Id_: bson.NewObjectId(), Title: form.Value("title"), Cover: form.Value("cover"), Author: form.Value("author"), Translator: form.Value("translator"), Pages: pages, Language: form.Value("language"), Publisher: form.Value("publisher"), PublicationDate: form.Value("publication_date"), Introduction: form.Value("introduction"), ISBN: form.Value("isbn"), }) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/books", http.StatusFound) return } } handler.renderTemplate("book/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) }
// URL: /admin/link_exchange/{linkExchangeId}/edit // 编辑友情链接 func adminEditLinkExchangeHandler(w http.ResponseWriter, r *http.Request) { linkExchangeId := mux.Vars(r)["linkExchangeId"] c := DB.C("link_exchanges") var linkExchange LinkExchange c.Find(bson.M{"_id": bson.ObjectIdHex(linkExchangeId)}).One(&linkExchange) form := wtforms.NewForm( wtforms.NewTextField("name", "名称", linkExchange.Name, wtforms.Required{}), wtforms.NewTextField("url", "URL", linkExchange.URL, wtforms.Required{}, wtforms.URL{}), wtforms.NewTextField("description", "描述", linkExchange.Description, wtforms.Required{}), wtforms.NewTextField("logo", "Logo", linkExchange.Logo), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/link_exchange_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": false, }) return } err := c.Update(bson.M{"_id": linkExchange.Id_}, bson.M{"$set": bson.M{ "name": form.Value("name"), "url": form.Value("url"), "description": form.Value("description"), "logo": form.Value("logo"), }}) if err != nil { panic(err) } http.Redirect(w, r, "/admin/link_exchanges", http.StatusFound) return } renderTemplate(w, r, "admin/link_exchange_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": false, }) }
// URL: /admin/ad/new // 添加广告 func adminNewAdHandler(w http.ResponseWriter, r *http.Request) { choices := []wtforms.Choice{ wtforms.Choice{"frongpage", "首页"}, wtforms.Choice{"2cols", "2列宽度"}, wtforms.Choice{"3cols", "3列宽度"}, wtforms.Choice{"4cols", "4列宽度"}, } form := wtforms.NewForm( wtforms.NewSelectField("position", "位置", choices, "", wtforms.Required{}), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), wtforms.NewTextArea("code", "代码", "", wtforms.Required{}), ) if r.Method == "POST" { if !form.Validate(r) { renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": true, }) return } c := DB.C("ads") err := c.Insert(&AD{ Id_: bson.NewObjectId(), Position: form.Value("position"), Name: form.Value("name"), Code: form.Value("code"), }) if err != nil { panic(err) } http.Redirect(w, r, "/admin/ads", http.StatusFound) return } renderTemplate(w, r, "admin/ad_form.html", map[string]interface{}{ "adminNav": ADMIN_NAV, "form": form, "isNew": true, }) }
// URL: /admin/package_category/new // 新建包分类 func adminNewPackageCategoryHandler(handler *Handler) { defer dps.Persist() form := wtforms.NewForm( wtforms.NewTextField("id", "ID", "", wtforms.Required{}), wtforms.NewTextField("name", "名称", "", wtforms.Required{}), ) if handler.Request.Method == "POST" { if !form.Validate(handler.Request) { handler.renderTemplate("package_category/form.html", ADMIN, map[string]interface{}{"form": form}) return } c := handler.DB.C(PACKAGE_CATEGORIES) var category PackageCategory err := c.Find(bson.M{"name": form.Value("name")}).One(&category) if err == nil { form.AddError("name", "该名称已经有了") handler.renderTemplate("package_category/form.html", ADMIN, map[string]interface{}{"form": form}) return } err = c.Insert(&PackageCategory{ Id_: bson.NewObjectId(), Id: form.Value("id"), Name: form.Value("name"), }) if err != nil { panic(err) } http.Redirect(handler.ResponseWriter, handler.Request, "/admin/package_category/new", http.StatusFound) } handler.renderTemplate("package_category/form.html", ADMIN, map[string]interface{}{ "form": form, "isNew": true, }) }
// URL: /reset/{code} // 用户点击邮件中的链接,根据code找到对应的用户,设置新密码,修改完成后清除code func resetPasswordHandler(handler *Handler) { vars := mux.Vars(handler.Request) code := vars["code"] var user User c := handler.DB.C(USERS) err := c.Find(bson.M{"resetcode": code}).One(&user) if err != nil { message(handler, "重设密码", `无效的重设密码标记,可能你已经重新设置过了或者链接已经失效,请通过<a href="/forgot_password">忘记密码</a>进行重设密码`, "error") return } form := wtforms.NewForm( wtforms.NewPasswordField("new_password", "新密码", wtforms.Required{}), wtforms.NewPasswordField("confirm_password", "确认新密码", wtforms.Required{}), ) if handler.Request.Method == "POST" && form.Validate(handler.Request) { if form.Value("new_password") == form.Value("confirm_password") { salt := strings.Replace(uuid.NewUUID().String(), "-", "", -1) c.Update( bson.M{"_id": user.Id_}, bson.M{ "$set": bson.M{ "password": encryptPassword(form.Value("new_password"), salt), "salt": salt, "resetcode": "", }, }, ) message(handler, "重设密码成功", `密码重设成功,你现在可以 <a href="/signin" class="btn btn-primary">登录</a> 了`, "success") return } else { form.AddError("confirm_password", "密码不匹配") } } handler.renderTemplate("account/reset_password.html", BASE, map[string]interface{}{"form": form, "code": code, "account": user.Username}) }
// URL: /reset/{code} // 用户点击邮件中的链接,根据code找到对应的用户,设置新密码,修改完成后清除code func resetPasswordHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) code := vars["code"] var user User c := DB.C("users") err := c.Find(bson.M{"resetcode": code}).One(&user) if err != nil { message(w, r, "重设密码", `无效的重设密码标记,可能你已经重新设置过了或者链接已经失效,请通过<a href="/forgot_password">忘记密码</a>进行重设密码`, "error") return } form := wtforms.NewForm( wtforms.NewPasswordField("new_password", "新密码", wtforms.Required{}), wtforms.NewPasswordField("confirm_password", "确认新密码", wtforms.Required{}), ) if r.Method == "POST" && form.Validate(r) { if form.Value("new_password") == form.Value("confirm_password") { c.Update( bson.M{"_id": user.Id_}, bson.M{ "$set": bson.M{ "password": encryptPassword(form.Value("new_password")), "resetcode": "", }, }, ) message(w, r, "重设密码成功", `密码重设成功,你现在可以 <a href="/signin" class="btn btn-primary">登录</a> 了`, "success") return } else { form.AddError("confirm_password", "密码不匹配") } } renderTemplate(w, r, "account/reset_password.html", map[string]interface{}{"form": form, "code": code, "account": user.Username}) }