diff --git a/app/controllers/AttachController.go b/app/controllers/AttachController.go index 90246d7..d7f2134 100644 --- a/app/controllers/AttachController.go +++ b/app/controllers/AttachController.go @@ -62,7 +62,7 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) { maxFileSize = 1000 } if(float64(len(data)) > maxFileSize * float64(1024*1024)) { - resultMsg = fmt.Sprintf("附件大于%vM", maxFileSize) + resultMsg = fmt.Sprintf("The file's size is bigger than %vM", maxFileSize) return re } @@ -100,11 +100,15 @@ func (c Attach) uploadAttach(noteId string) (re info.Re) { id := bson.NewObjectId(); fileInfo.AttachId = id fileId = id.Hex() - Ok = attachService.AddAttach(fileInfo) + Ok, resultMsg = attachService.AddAttach(fileInfo) + if resultMsg != "" { + resultMsg = c.Message(resultMsg) + } fileInfo.Path = ""; // 不要返回 - resultMsg = "success" - + if Ok { + resultMsg = "success" + } return re } @@ -212,4 +216,4 @@ func (c Attach) DownloadAll(noteId string) revel.Result { // file, _ := os.Open(dir + "/" + filename) // fw.Seek(0, 0) return c.RenderBinary(fw, filename, revel.Attachment, time.Now()) // revel.Attachment -} \ No newline at end of file +} diff --git a/app/controllers/AuthController.go b/app/controllers/AuthController.go index 3814668..8cd0d5b 100644 --- a/app/controllers/AuthController.go +++ b/app/controllers/AuthController.go @@ -91,18 +91,19 @@ func (c Auth) Demo() revel.Result { //-------- // 注册 -func (c Auth) Register(from string) revel.Result { +func (c Auth) Register(from, iu string) revel.Result { if !configService.IsOpenRegister() { return c.Redirect("/index") } c.SetLocale() c.RenderArgs["from"] = from + c.RenderArgs["iu"] = iu c.RenderArgs["title"] = c.Message("register") c.RenderArgs["subTitle"] = c.Message("register") return c.RenderTemplate("home/register.html") } -func (c Auth) DoRegister(email, pwd string) revel.Result { +func (c Auth) DoRegister(email, pwd, iu string) revel.Result { if !configService.IsOpenRegister() { return c.Redirect("/index") } @@ -117,7 +118,7 @@ func (c Auth) DoRegister(email, pwd string) revel.Result { } // 注册 - re.Ok, re.Msg = authService.Register(email, pwd) + re.Ok, re.Msg = authService.Register(email, pwd, iu) // 注册成功, 则立即登录之 if re.Ok { diff --git a/app/controllers/BaseController.go b/app/controllers/BaseController.go index fcef661..e82be4a 100644 --- a/app/controllers/BaseController.go +++ b/app/controllers/BaseController.go @@ -193,12 +193,13 @@ func (c BaseController) SetLocale() string { } // 设置userInfo -func (c BaseController) SetUserInfo() { +func (c BaseController) SetUserInfo() info.User { userInfo := c.GetUserInfo() c.RenderArgs["userInfo"] = userInfo if(userInfo.Username == configService.GetAdminUsername()) { c.RenderArgs["isAdmin"] = true } + return userInfo } // life @@ -224,6 +225,7 @@ func (c BaseController) RenderTemplateStr(templatePath string) string { // 为了msg // msg-v1-v2-v3 func (c BaseController) RenderRe(re info.Re) revel.Result { + oldMsg := re.Msg if re.Msg != "" { if(strings.Contains(re.Msg, "-")) { msgAndValues := strings.Split(re.Msg, "-") @@ -241,5 +243,8 @@ func (c BaseController) RenderRe(re info.Re) revel.Result { re.Msg = c.Message(re.Msg) } } + if strings.HasPrefix(re.Msg, "???") { + re.Msg = oldMsg + } return c.RenderJson(re) } diff --git a/app/controllers/BlogController.go b/app/controllers/BlogController.go index 088ddf8..98c6c36 100644 --- a/app/controllers/BlogController.go +++ b/app/controllers/BlogController.go @@ -57,6 +57,9 @@ func (c Blog) render(templateName string, themePath string) revel.Result { isPreview = true themePath = themePath2.(string) c.setPreviewUrl() + + // 因为common的themeInfo是从UserBlog.ThemeId来取的, 所以这里要fugai下 + c.RenderArgs["themeInfo"] = c.RenderArgs["themeInfoPreview"]; } return blog.RenderTemplate(templateName, c.RenderArgs, revel.BasePath+"/"+themePath, isPreview) } @@ -846,4 +849,4 @@ func (c Blog) ListCateLatest(notebookId, callback string) revel.Result { re.Ok = true re.List = blogs return c.RenderJsonP(callback, re) -} \ No newline at end of file +} diff --git a/app/controllers/FileController.go b/app/controllers/FileController.go index 7e4a4b7..49f4d1e 100644 --- a/app/controllers/FileController.go +++ b/app/controllers/FileController.go @@ -10,7 +10,7 @@ import ( "io/ioutil" "os" "fmt" - "strconv" +// "strconv" "strings" ) @@ -85,7 +85,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) { var fileUrlPath = "" var fileId = "" var resultCode = 0 // 1表示正常 - var resultMsg = "内部错误" // 错误信息 + var resultMsg = "error" // 错误信息 var Ok = false defer func() { @@ -120,7 +120,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) { } else { _, ext = SplitFilename(filename) if(ext != ".gif" && ext != ".jpg" && ext != ".png" && ext != ".bmp" && ext != ".jpeg") { - resultMsg = "不是图片" + resultMsg = "Please upload image" return re } } @@ -147,7 +147,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) { // > 2M? if(float64(len(data)) > maxFileSize * float64(1024*1024)) { resultCode = 0 - resultMsg = fmt.Sprintf("图片大于%vM", maxFileSize) + resultMsg = fmt.Sprintf("The file Size is bigger than %vM", maxFileSize) return re } @@ -163,7 +163,7 @@ func (c File) uploadImage(from, albumId string) (re info.Re) { filesize := GetFilesize(toPathGif) fileUrlPath += "/" + filename resultCode = 1 - resultMsg = "上传成功!" + resultMsg = "Upload Success!" // File fileInfo := info.File{Name: filename, @@ -178,7 +178,8 @@ func (c File) uploadImage(from, albumId string) (re info.Re) { fileId = "public/upload/" + c.GetUserId() + "/images/logo/" + filename } - Ok = fileService.AddImage(fileInfo, albumId, c.GetUserId()) + Ok, resultMsg = fileService.AddImage(fileInfo, albumId, c.GetUserId(), from == "" || from == "pasteImage") + resultMsg = c.Message(resultMsg) fileInfo.Path = ""; // 不要返回 re.Item = fileInfo @@ -203,55 +204,6 @@ func (c File) DeleteImage(fileId string) revel.Result { re.Ok, re.Msg = fileService.DeleteImage(c.GetUserId(), fileId) return c.RenderJson(re) } - -// update image uploader to leaui image, -// scan all user's images and insert into db -func (c File) UpgradeLeauiImage() revel.Result { - re := info.NewRe() - - if ok, _ := revel.Config.Bool("upgradeLeauiImage"); !ok { - re.Msg = "Not allowed" - return c.RenderJson(re) - } - - uploadPath := revel.BasePath + "/public/upload"; - userIds := ListDir(uploadPath) - if userIds == nil { - re.Msg = "no user" - return c.RenderJson(re) - } - - msg := ""; - - for _, userId := range userIds { - dirPath := uploadPath + "/" + userId + "/images" - images := ListDir(dirPath) - if images == nil { - msg += userId + " no images " - continue; - } - - hadImages := fileService.GetAllImageNamesMap(userId) - - i := 0 - for _, filename := range images { - if _, ok := hadImages[filename]; !ok { - fileUrlPath := "/upload/" + userId + "/images/" + filename - fileInfo := info.File{Name: filename, - Title: filename, - Path: fileUrlPath, - Size: GetFilesize(dirPath + "/" + filename)} - fileService.AddImage(fileInfo, "", userId) - i++ - } - } - msg += userId + ": " + strconv.Itoa(len(images)) + " -- " + strconv.Itoa(i) + " images " - } - - re.Msg = msg - return c.RenderJson(re) -} - //----------- // 输出image @@ -267,15 +219,15 @@ func (c File) OutputImage(noteId, fileId string) revel.Result { } // 协作时复制图片到owner +// 需要计算对方大小 func (c File) CopyImage(userId, fileId, toUserId string) revel.Result { re := info.NewRe() - re.Ok, re.Id = fileService.CopyImage(userId, fileId, toUserId) - return c.RenderJson(re) } // 复制外网的图片, 成公共图片 放在/upload下 +// 都要好好的计算大小 func (c File) CopyHttpImage(src string) revel.Result { re := info.NewRe() fileUrlPath := "upload/" + c.GetUserId() + "/images" @@ -302,29 +254,7 @@ func (c File) CopyHttpImage(src string) revel.Result { re.Id = id.Hex() re.Item = fileInfo.Path - re.Ok = fileService.AddImage(fileInfo, "", c.GetUserId()) + re.Ok, re.Msg = fileService.AddImage(fileInfo, "", c.GetUserId(), true) return c.RenderJson(re) -} - -//------------ -// 过时 已弃用! -func (c File) UploadImage(renderHtml string) revel.Result { - if renderHtml == "" { - renderHtml = "file/image.html" - } - - re := c.uploadImage("", ""); - - c.RenderArgs["fileUrlPath"] = configService.GetSiteUrl() + re.Id - c.RenderArgs["resultCode"] = re.Code - c.RenderArgs["resultMsg"] = re.Msg - - return c.RenderTemplate(renderHtml) -} - -// 已弃用 -func (c File) UploadImageJson(from, noteId string) revel.Result { - re := c.uploadImage(from, ""); - return c.RenderJson(re) -} +} \ No newline at end of file diff --git a/app/controllers/NoteController.go b/app/controllers/NoteController.go index cd75c54..59c43bb 100644 --- a/app/controllers/NoteController.go +++ b/app/controllers/NoteController.go @@ -22,9 +22,8 @@ type Note struct { // 笔记首页, 判断是否已登录 // 已登录, 得到用户基本信息(notebook, shareNotebook), 跳转到index.html中 // 否则, 转向登录页面 -func (c Note) Index() revel.Result { +func (c Note) Index(noteId string) revel.Result { c.SetLocale() - userInfo := c.GetUserInfo() userId := userInfo.UserId.Hex() @@ -35,7 +34,7 @@ func (c Note) Index() revel.Result { } c.RenderArgs["openRegister"] = configService.IsOpenRegister() - + // 已登录了, 那么得到所有信息 notebooks := notebookService.GetNotebooks(userId) shareNotebooks, sharedUserInfos := shareService.GetShareNotebooks(userId) @@ -43,22 +42,78 @@ func (c Note) Index() revel.Result { // 还需要按时间排序(DESC)得到notes notes := []info.Note{} noteContent := info.NoteContent{} + if len(notebooks) > 0 { -// _, notes = noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), pageSize, defaultSortField, false, false); - // 变成最新 - _, notes = noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), 50, defaultSortField, false, false); - if len(notes) > 0 { - noteContent = noteService.GetNoteContent(notes[0].NoteId.Hex(), userId) + // noteId是否存在 + // 是否传入了正确的noteId + hasRightNoteId := false + if IsObjectId(noteId) { + note := noteService.GetNoteById(noteId) + var noteOwner = note.UserId.Hex() + noteContent = noteService.GetNoteContent(noteId, noteOwner) + + if note.NoteId != "" { + hasRightNoteId = true + c.RenderArgs["curNoteId"] = noteId + c.RenderArgs["curNotebookId"] = note.NotebookId.Hex() + + // 打开的是共享的笔记, 那么判断是否是共享给我的默认笔记 + if noteOwner != c.GetUserId() { + if shareService.HasReadPerm(noteOwner, c.GetUserId(), noteId) { + // 不要获取notebook下的笔记 + // 在前端下发请求 + c.RenderArgs["curSharedNoteNotebookId"] = note.NotebookId.Hex() + c.RenderArgs["curSharedUserId"] = noteOwner; + // 没有读写权限 + } else { + hasRightNoteId = false + } + } else { + _, notes = noteService.ListNotes(c.GetUserId(), note.NotebookId.Hex(), false, c.GetPage(), 50, defaultSortField, false, false); + + // 如果指定了某笔记, 则该笔记放在首位 + lenNotes := len(notes) + if lenNotes > 1 { + notes2 := make([]info.Note, len(notes)) + notes2[0] = note + i := 1 + for _, note := range notes { + if note.NoteId.Hex() != noteId { + if i == lenNotes { // 防止越界 + break; + } + notes2[i] = note + i++ + } + } + notes = notes2 + } + } + } + + // 得到最近的笔记 + _, latestNotes := noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), 50, defaultSortField, false, false); + c.RenderArgs["latestNotes"] = latestNotes + } + + // 没有传入笔记 + // 那么得到最新笔记 + if !hasRightNoteId { + _, notes = noteService.ListNotes(c.GetUserId(), "", false, c.GetPage(), 50, defaultSortField, false, false); + if len(notes) > 0 { + noteContent = noteService.GetNoteContent(notes[0].NoteId.Hex(), userId) + c.RenderArgs["curNoteId"] = notes[0].NoteId.Hex() + } } } + // 当然, 还需要得到第一个notes的content //... - Log(configService.GetAdminUsername()) c.RenderArgs["isAdmin"] = configService.GetAdminUsername() == userInfo.Username c.RenderArgs["userInfo"] = userInfo c.RenderArgs["notebooks"] = notebooks - c.RenderArgs["shareNotebooks"] = shareNotebooks + c.RenderArgs["shareNotebooks"] = shareNotebooks // note信息在notes列表中 c.RenderArgs["sharedUserInfos"] = sharedUserInfos c.RenderArgs["notes"] = notes @@ -69,6 +124,9 @@ func (c Note) Index() revel.Result { c.RenderArgs["globalConfigs"] = configService.GetGlobalConfigForUser() + +// return c.RenderTemplate("note/note.html") + if isDev, _ := revel.Config.Bool("mode.dev"); isDev { return c.RenderTemplate("note/note-dev.html") } else { diff --git a/app/controllers/PreviewController.go b/app/controllers/PreviewController.go index 03cfca9..f24afa8 100644 --- a/app/controllers/PreviewController.go +++ b/app/controllers/PreviewController.go @@ -33,6 +33,8 @@ func (c Preview) getPreviewThemeAbsolutePath(themeId string) bool { theme := themeService.GetTheme(c.GetUserId(), themeId) c.RenderArgs["isPreview"] = true + c.RenderArgs["themeId"] = themeId + c.RenderArgs["themeInfoPreview"] = theme.Info c.RenderArgs["themePath"] = theme.Path if theme.Path == "" { return false diff --git a/app/controllers/admin/AdminUserController.go b/app/controllers/admin/AdminUserController.go index e44eb4f..8e2ba65 100644 --- a/app/controllers/admin/AdminUserController.go +++ b/app/controllers/admin/AdminUserController.go @@ -44,7 +44,7 @@ func (c AdminUser) Register(email, pwd string) revel.Result { } // 注册 - re.Ok, re.Msg = authService.Register(email, pwd) + re.Ok, re.Msg = authService.Register(email, pwd, "") return c.RenderRe(re) } diff --git a/app/controllers/member/MemberBlogController.go b/app/controllers/member/MemberBlogController.go index 97359b1..2ae4c3e 100644 --- a/app/controllers/member/MemberBlogController.go +++ b/app/controllers/member/MemberBlogController.go @@ -1,15 +1,15 @@ package member import ( - "github.com/revel/revel" - . "github.com/leanote/leanote/app/lea" - "github.com/leanote/leanote/app/info" - "os" - "io/ioutil" - "time" "fmt" + "github.com/leanote/leanote/app/info" + . "github.com/leanote/leanote/app/lea" + "github.com/revel/revel" + "io/ioutil" + "os" "strings" -// "github.com/leanote/leanote/app/lea/blog" + "time" + // "github.com/leanote/leanote/app/lea/blog" ) // 博客管理 @@ -28,35 +28,34 @@ func (c MemberBlog) common() info.UserBlog { userBlog := blogService.GetUserBlog(userId) c.RenderArgs["userBlog"] = userBlog - + c.SetUserInfo() c.SetLocale() return userBlog } - // 得到sorterField 和 isAsc // okSorter = ['email', 'username'] -func (c MemberBlog) getSorter(sorterField string, isAsc bool, okSorter []string) (string, bool){ +func (c MemberBlog) getSorter(sorterField string, isAsc bool, okSorter []string) (string, bool) { sorter := "" c.Params.Bind(&sorter, "sorter") if sorter == "" { - return sorterField, isAsc; + return sorterField, isAsc } - + // sorter形式 email-up, email-down s2 := strings.Split(sorter, "-") if len(s2) != 2 { - return sorterField, isAsc; + return sorterField, isAsc } - + // 必须是可用的sorter if okSorter != nil && len(okSorter) > 0 { if !InArray(okSorter, s2[0]) { - return sorterField, isAsc; + return sorterField, isAsc } } - + sorterField = strings.Title(s2[0]) if s2[1] == "up" { isAsc = true @@ -64,28 +63,29 @@ func (c MemberBlog) getSorter(sorterField string, isAsc bool, okSorter []string) isAsc = false } c.RenderArgs["sorter"] = sorter - return sorterField, isAsc; + return sorterField, isAsc } // 博客列表 var userPageSize = 15 + func (c MemberBlog) Index(sorter, keywords string) revel.Result { userId := c.GetUserId() userInfo := userService.GetUserInfo(userId) c.RenderArgs["userInfo"] = userInfo - + c.RenderArgs["title"] = "Posts" pageNumber := c.GetPage() - sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "urlTitle", "updatedTime", "publicTime", "createdTime"}); - pageInfo, blogs := blogService.ListAllBlogs(c.GetUserId(), "", keywords, false, pageNumber, userPageSize, sorterField, isAsc); + sorterField, isAsc := c.getSorter("CreatedTime", false, []string{"title", "urlTitle", "updatedTime", "publicTime", "createdTime"}) + pageInfo, blogs := blogService.ListAllBlogs(c.GetUserId(), "", keywords, false, pageNumber, userPageSize, sorterField, isAsc) c.RenderArgs["pageInfo"] = pageInfo c.RenderArgs["blogs"] = blogs c.RenderArgs["keywords"] = keywords - + userAndBlog := userService.GetUserAndBlog(c.GetUserId()) c.RenderArgs["userAndBlog"] = userAndBlog - - return c.RenderTemplate("member/blog/list.html"); + + return c.RenderTemplate("member/blog/list.html") } // 修改笔记的urlTitle @@ -95,17 +95,16 @@ func (c MemberBlog) UpdateBlogUrlTitle(noteId, urlTitle string) revel.Result { return c.RenderJson(re) } - // 修改笔记的urlTitle func (c MemberBlog) UpdateBlogAbstract(noteId string) revel.Result { c.RenderArgs["title"] = "Update Post Abstract" - note := noteService.GetNoteAndContent(noteId, c.GetUserId()); + note := noteService.GetNoteAndContent(noteId, c.GetUserId()) if !note.Note.IsBlog { - return c.E404(); + return c.E404() } c.RenderArgs["note"] = note c.RenderArgs["noteId"] = noteId - return c.RenderTemplate("member/blog/update_abstract.html"); + return c.RenderTemplate("member/blog/update_abstract.html") } func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string) revel.Result { @@ -118,38 +117,33 @@ func (c MemberBlog) DoUpdateBlogAbstract(noteId, imgSrc, desc, abstract string) func (c MemberBlog) Base() revel.Result { c.common() c.RenderArgs["title"] = "Blog Base Info" - return c.RenderTemplate("member/blog/base.html"); + return c.RenderTemplate("member/blog/base.html") } func (c MemberBlog) Comment() revel.Result { c.common() c.RenderArgs["title"] = "Comment" - return c.RenderTemplate("member/blog/comment.html"); -} -func (c MemberBlog) Domain() revel.Result { - c.common() - c.RenderArgs["title"] = "Domain" - return c.RenderTemplate("member/blog/domain.html"); + return c.RenderTemplate("member/blog/comment.html") } func (c MemberBlog) Paging() revel.Result { c.common() c.RenderArgs["title"] = "Paging" - return c.RenderTemplate("member/blog/paging.html"); + return c.RenderTemplate("member/blog/paging.html") } func (c MemberBlog) Cate() revel.Result { userBlog := c.common() c.RenderArgs["title"] = "Cate" - + notebooks := blogService.ListBlogNotebooks(c.GetUserId()) notebooksMap := map[string]info.Notebook{} for _, each := range notebooks { notebooksMap[each.NotebookId.Hex()] = each } - - var i = 0; + + var i = 0 notebooks2 := make([]info.Notebook, len(notebooks)) - + // 先要保证已有的是正确的排序 cateIds := userBlog.CateIds has := map[string]bool{} // cateIds中有的 @@ -171,8 +165,8 @@ func (c MemberBlog) Cate() revel.Result { } } c.RenderArgs["notebooks"] = notebooks2 - - return c.RenderTemplate("member/blog/cate.html"); + + return c.RenderTemplate("member/blog/cate.html") } // 修改分类排序 @@ -199,9 +193,10 @@ func (c MemberBlog) AddOrUpdateSingle(singleId string) revel.Result { c.RenderArgs["title"] = "Add Single" c.RenderArgs["singleId"] = singleId if singleId != "" { + c.RenderArgs["title"] = "Update Single" c.RenderArgs["single"] = blogService.GetSingle(singleId) } - return c.RenderTemplate("member/blog/add_single.html"); + return c.RenderTemplate("member/blog/add_single.html") } func (c MemberBlog) SortSingles(singleIds []string) revel.Result { re := info.NewRe() @@ -226,8 +221,8 @@ func (c MemberBlog) Single() revel.Result { c.common() c.RenderArgs["title"] = "Cate" c.RenderArgs["singles"] = blogService.GetSingles(c.GetUserId()) - - return c.RenderTemplate("member/blog/single.html"); + + return c.RenderTemplate("member/blog/single.html") } // 主题 @@ -236,15 +231,16 @@ func (c MemberBlog) Theme() revel.Result { activeTheme, otherThemes := themeService.GetUserThemes(c.GetUserId()) c.RenderArgs["activeTheme"] = activeTheme c.RenderArgs["otherThemes"] = otherThemes - + c.RenderArgs["optionThemes"] = themeService.GetDefaultThemes() - + c.RenderArgs["title"] = "Theme" - return c.RenderTemplate("member/blog/theme.html"); + return c.RenderTemplate("member/blog/theme.html") } // 编辑主题 var baseTpls = []string{"header.html", "footer.html", "index.html", "cate.html", "search.html", "post.html", "single.html", "tags.html", "tag_posts.html", "archive.html", "share_comment.html", "404.html", "theme.json", "style.css", "blog.js"} + func (c MemberBlog) UpdateTheme(themeId string, isNew int) revel.Result { // 查看用户是否有该theme, 若没有则复制default之 // 得到主题的文件列表 @@ -253,22 +249,25 @@ func (c MemberBlog) UpdateTheme(themeId string, isNew int) revel.Result { _, themeId = themeService.NewThemeForFirst(userBlog) return c.Redirect("/member/blog/updateTheme?themeId=" + themeId) } - + c.common() c.RenderArgs["title"] = "Upate Theme" c.RenderArgs["isNew"] = isNew - + // 先复制之 c.RenderArgs["themeId"] = themeId - + // 得到脚本目录 userId := c.GetUserId() - - theme := themeService.GetTheme(userId, themeId) + + theme := themeService.GetTheme(userId, themeId) + if theme.ThemeId == "" { + return c.E404() + } c.RenderArgs["theme"] = theme - + path := revel.BasePath + "/" + theme.Path - + tpls := ListDir(path) myTpls := make([]string, len(baseTpls)) tplMap := map[string]bool{} @@ -279,16 +278,16 @@ func (c MemberBlog) UpdateTheme(themeId string, isNew int) revel.Result { // 得到没有的tpls for _, t := range tpls { if t == "images" { - continue; + continue } if !tplMap[t] { myTpls = append(myTpls, t) } } - + c.RenderArgs["myTpls"] = myTpls - - return c.RenderTemplate("member/blog/update_theme.html"); + + return c.RenderTemplate("member/blog/update_theme.html") } // 得到文件内容 @@ -296,13 +295,13 @@ func (c MemberBlog) GetTplContent(themeId string, filename string) revel.Result re := info.NewRe() re.Ok = true re.Item = themeService.GetTplContent(c.GetUserId(), themeId, filename) - + return c.RenderJson(re) } func (c MemberBlog) UpdateTplContent(themeId, filename, content string) revel.Result { re := info.NewRe() re.Ok, re.Msg = themeService.UpdateTplContent(c.GetUserId(), themeId, filename, content) - return c.RenderJson(re) + return c.RenderRe(re) } func (c MemberBlog) DeleteTpl(themeId, filename string) revel.Result { @@ -331,7 +330,7 @@ func (c MemberBlog) DeleteThemeImage(themeId, filename string) revel.Result { // 上传主题图片 func (c MemberBlog) UploadThemeImage(themeId string) revel.Result { - re := c.uploadImage(themeId); + re := c.uploadImage(themeId) c.RenderArgs["fileUrlPath"] = re.Id c.RenderArgs["resultCode"] = re.Code c.RenderArgs["resultMsg"] = re.Msg @@ -339,17 +338,17 @@ func (c MemberBlog) UploadThemeImage(themeId string) revel.Result { } func (c MemberBlog) uploadImage(themeId string) (re info.Re) { var fileId = "" - var resultCode = 0 // 1表示正常 + var resultCode = 0 // 1表示正常 var resultMsg = "内部错误" // 错误信息 var Ok = false - + defer func() { re.Id = fileId // 只是id, 没有其它信息 re.Code = resultCode re.Msg = resultMsg re.Ok = Ok }() - + file, handel, err := c.Request.FormFile("file") if err != nil { return re @@ -363,11 +362,11 @@ func (c MemberBlog) uploadImage(themeId string) (re info.Re) { } // 生成新的文件名 filename := handel.Filename - - var ext string; - + + var ext string + _, ext = SplitFilename(filename) - if(ext != ".gif" && ext != ".jpg" && ext != ".png" && ext != ".bmp" && ext != ".jpeg") { + if ext != ".gif" && ext != ".jpg" && ext != ".png" && ext != ".bmp" && ext != ".jpeg" { resultMsg = "不是图片" return re } @@ -378,15 +377,15 @@ func (c MemberBlog) uploadImage(themeId string) (re info.Re) { LogJ(err) return re } - + // > 2M? - if(len(data) > 5 * 1024 * 1024) { + if len(data) > 5*1024*1024 { resultCode = 0 resultMsg = "图片大于2M" return re } - - toPath := dir + "/" + filename; + + toPath := dir + "/" + filename err = ioutil.WriteFile(toPath, data, 0777) if err != nil { LogJ(err) @@ -395,7 +394,7 @@ func (c MemberBlog) uploadImage(themeId string) (re info.Re) { TransToGif(toPath, 0, true) resultCode = 1 resultMsg = "上传成功!" - + return re } @@ -406,18 +405,21 @@ func (c MemberBlog) ActiveTheme(themeId string) revel.Result { re.Ok = themeService.ActiveTheme(c.GetUserId(), themeId) return c.RenderJson(re) } + // 删除主题 func (c MemberBlog) DeleteTheme(themeId string) revel.Result { re := info.NewRe() re.Ok = themeService.DeleteTheme(c.GetUserId(), themeId) return c.RenderJson(re) } + // 管理员公开主题 func (c MemberBlog) PublicTheme(themeId string) revel.Result { re := info.NewRe() re.Ok = themeService.PublicTheme(c.GetUserId(), themeId) return c.RenderJson(re) } + // 导出 func (c MemberBlog) ExportTheme(themeId string) revel.Result { re := info.NewRe() @@ -427,21 +429,21 @@ func (c MemberBlog) ExportTheme(themeId string) revel.Result { return c.RenderText("error...") } fw, err := os.Open(path) - if err != nil { + if err != nil { return c.RenderText("error") - } - return c.RenderBinary(fw, GetFilename(path), revel.Attachment, time.Now()) // revel.Attachment + } + return c.RenderBinary(fw, GetFilename(path), revel.Attachment, time.Now()) // revel.Attachment } // 导入主题 func (c MemberBlog) ImportTheme() revel.Result { re := info.NewRe() - + file, handel, err := c.Request.FormFile("file") if err != nil { re.Msg = fmt.Sprintf("%v", err) return c.RenderJson(re) - + } defer file.Close() // 生成上传路径 @@ -454,10 +456,10 @@ func (c MemberBlog) ImportTheme() revel.Result { } // 生成新的文件名 filename := handel.Filename - - var ext string; + + var ext string _, ext = SplitFilename(filename) - if(ext != ".zip") { + if ext != ".zip" { re.Msg = "请上传zip文件" return c.RenderJson(re) } @@ -467,40 +469,40 @@ func (c MemberBlog) ImportTheme() revel.Result { if err != nil { return c.RenderJson(re) } - + // > 10M? - if(len(data) > 10 * 1024 * 1024) { + if len(data) > 10*1024*1024 { re.Msg = "文件大于10M" return c.RenderJson(re) } - - toPath := dir + "/" + filename; + + toPath := dir + "/" + filename err = ioutil.WriteFile(toPath, data, 0777) if err != nil { re.Msg = fmt.Sprintf("%v", err) return c.RenderJson(re) } - + // 上传好后, 增加之 - themeService.ImportTheme(c.GetUserId(), toPath) - - re.Ok = true - return c.RenderJson(re) + re.Ok, re.Msg = themeService.ImportTheme(c.GetUserId(), toPath) + return c.RenderRe(re) } - + // 安装 func (c MemberBlog) InstallTheme(themeId string) revel.Result { re := info.NewRe() re.Ok = themeService.InstallTheme(c.GetUserId(), themeId) return c.RenderJson(re) } + // 新建主题 func (c MemberBlog) NewTheme() revel.Result { _, themeId := themeService.NewTheme(c.GetUserId()) return c.Redirect("/member/blog/updateTheme?isNew=1&themeId=" + themeId) } + //----------- -// +// func (c MemberBlog) SetUserBlogBase(userBlog info.UserBlogBase) revel.Result { re := info.NewRe() re.Ok = blogService.UpdateUserBlogBase(c.GetUserId(), userBlog) @@ -516,6 +518,7 @@ func (c MemberBlog) SetUserBlogStyle(userBlog info.UserBlogStyle) revel.Result { re.Ok = blogService.UpdateUserBlogStyle(c.GetUserId(), userBlog) return c.RenderJson(re) } + func (c MemberBlog) SetUserBlogPaging(perPageSize int, sortField string, isAsc bool) revel.Result { re := info.NewRe() re.Ok, re.Msg = blogService.UpdateUserBlogPaging(c.GetUserId(), perPageSize, sortField, isAsc) diff --git a/app/controllers/member/MemberGroupController.go b/app/controllers/member/MemberGroupController.go index 815857d..345a95d 100644 --- a/app/controllers/member/MemberGroupController.go +++ b/app/controllers/member/MemberGroupController.go @@ -35,7 +35,7 @@ func (c MemberGroup) UpdateGroupTitle(groupId, title string) revel.Result { func (c MemberGroup) DeleteGroup(groupId string) revel.Result { re := info.NewRe() re.Ok, re.Msg = groupService.DeleteGroup(c.GetUserId(), groupId) - return c.RenderJson(re) + return c.RenderRe(re) } // 添加用户 diff --git a/app/controllers/member/init.go b/app/controllers/member/init.go index d891db2..b52edb0 100644 --- a/app/controllers/member/init.go +++ b/app/controllers/member/init.go @@ -128,6 +128,7 @@ func init() { revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberIndex{}) revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberUser{}) revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberBlog{}) + revel.InterceptFunc(AuthInterceptor, revel.BEFORE, &MemberGroup{}) revel.OnAppStart(func() { }) -} +} \ No newline at end of file diff --git a/app/db/Mgo.go b/app/db/Mgo.go index 37b0bdb..684ae10 100644 --- a/app/db/Mgo.go +++ b/app/db/Mgo.go @@ -3,6 +3,7 @@ package db import ( "fmt" "github.com/revel/revel" + . "github.com/leanote/leanote/app/lea" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" ) @@ -56,12 +57,15 @@ var Themes *mgo.Collection var Sessions *mgo.Collection // 初始化时连接数据库 -func Init() { - var url string - var ok bool +func Init(url, dbname string) { + ok := true config := revel.Config - url, ok = config.String("db.url") - dbname, _ := config.String("db.dbname") + if url == "" { + url, ok = config.String("db.url") + } + if dbname == "" { + dbname, _ = config.String("db.dbname") + } if !ok { host, _ := revel.Config.String("db.host") port, _ := revel.Config.String("db.port") @@ -73,6 +77,7 @@ func Init() { } url = "mongodb://" + usernameAndPassword + host + ":" + port + "/" + dbname } + Log(url) // [mongodb://][user:pass@]host1[:port1][,host2[:port2],...][/database][?options] // mongodb://myuser:mypass@localhost:40001,otherhost:40001/mydb diff --git a/app/info/UserInfo.go b/app/info/UserInfo.go index 7d4e49d..abd06e3 100644 --- a/app/info/UserInfo.go +++ b/app/info/UserInfo.go @@ -41,7 +41,7 @@ type User struct { ImageSize int `bson:"ImageSize" json:"-"` // 图片大小 AttachNum int `bson:"AttachNum" json:"-"` // 附件数量 AttachSize int `bson:"AttachSize" json:"-"` // 附件大小 - PerAttachSize int `bson:"PerAttachSize" json:"-"` // 单个附件大小 + FromUserId bson.ObjectId `FromUserId,omitempty` // 邀请的用户 AccountType string `bson:"AccountType" json:"-"` // normal(为空), premium AccountStartTime time.Time `bson:"AccountStartTime" json:"-"` // 开始日期 diff --git a/app/init.go b/app/init.go index 604bf4d..2c74049 100644 --- a/app/init.go +++ b/app/init.go @@ -1,67 +1,66 @@ package app import ( - "encoding/json" - "fmt" + "github.com/revel/revel" + . "github.com/leanote/leanote/app/lea" + "github.com/leanote/leanote/app/service" + "github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/controllers" "github.com/leanote/leanote/app/controllers/admin" "github.com/leanote/leanote/app/controllers/member" - "github.com/leanote/leanote/app/db" - . "github.com/leanote/leanote/app/lea" _ "github.com/leanote/leanote/app/lea/binder" + "github.com/leanote/leanote/app/lea/session" "github.com/leanote/leanote/app/lea/memcache" "github.com/leanote/leanote/app/lea/route" - "github.com/leanote/leanote/app/lea/session" - "github.com/leanote/leanote/app/service" - "github.com/revel/revel" + "reflect" + "fmt" "html/template" "math" - "net/url" - "reflect" - "strconv" "strings" + "strconv" "time" + "encoding/json" + "net/url" ) func init() { // Filters is the default set of global filters. revel.Filters = []revel.Filter{ - revel.PanicFilter, // Recover from panics and display an error page instead. + revel.PanicFilter, // Recover from panics and display an error page instead. route.RouterFilter, // revel.RouterFilter, // Use the routing table to select the right Action // AuthFilter, // Invoke the action. revel.FilterConfiguringFilter, // A hook for adding or removing per-Action filters. revel.ParamsFilter, // Parse parameters into Controller.Params. // revel.SessionFilter, // Restore and write the session cookie. - + // 使用SessionFilter标准版从cookie中得到sessionID, 然后通过MssessionFilter从Memcache中得到 // session, 之后MSessionFilter将session只存sessionID然后返回给SessionFilter返回到web - session.SessionFilter, // leanote session - // session.MSessionFilter, // leanote memcache session - - revel.FlashFilter, // Restore and write the flash cookie. - revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie. - revel.I18nFilter, // Resolve the requested language - revel.InterceptorFilter, // Run interceptors around the action. - revel.CompressFilter, // Compress the result. - revel.ActionInvoker, // Invoke the action. + session.SessionFilter, // leanote session + // session.MSessionFilter, // leanote memcache session + + revel.FlashFilter, // Restore and write the flash cookie. + revel.ValidationFilter, // Restore kept validation errors and save new ones from cookie. + revel.I18nFilter, // Resolve the requested language + revel.InterceptorFilter, // Run interceptors around the action. + revel.CompressFilter, // Compress the result. + revel.ActionInvoker, // Invoke the action. } - - //自定义模版函数 + revel.TemplateFuncs["raw"] = func(str string) template.HTML { return template.HTML(str) } revel.TemplateFuncs["add"] = func(i int) string { - i = i + 1 + i = i + 1; return fmt.Sprintf("%v", i) } revel.TemplateFuncs["sub"] = func(i int) int { - i = i - 1 + i = i - 1; return i } // 增加或减少 revel.TemplateFuncs["incr"] = func(n, i int) int { - n = n + i + n = n + i; return n } revel.TemplateFuncs["join"] = func(arr []string) template.HTML { @@ -85,11 +84,11 @@ func init() { return v.Get("a") } revel.TemplateFuncs["json"] = func(i interface{}) string { - b, _ := json.Marshal(i) + b, _ := json.Marshal(i) return string(b) } revel.TemplateFuncs["jsonJs"] = func(i interface{}) template.JS { - b, _ := json.Marshal(i) + b, _ := json.Marshal(i) return template.JS(string(b)) } revel.TemplateFuncs["datetime"] = func(t time.Time) template.HTML { @@ -103,15 +102,16 @@ func init() { t := time.Unix(int64(sec), 0) return template.HTML(t.Format("2006-01-02 15:04:05")) } - + // interface是否有该字段 revel.TemplateFuncs["has"] = func(i interface{}, key string) bool { - t := reflect.TypeOf(i) + t := reflect.TypeOf(i) _, ok := t.FieldByName(key) return ok } // tags + // 2014/12/30 标签添加链接 revel.TemplateFuncs["blogTags"] = func(renderArgs map[string]interface{}, tags []string) template.HTML { if tags == nil || len(tags) == 0 { return "" @@ -119,70 +119,120 @@ func init() { locale, _ := renderArgs[revel.CurrentLocaleRenderArg].(string) tagStr := "" lenTags := len(tags) + + tagPostUrl, _ := renderArgs["tagPostsUrl"].(string) + for i, tag := range tags { str := revel.Message(locale, tag) + var classes = "label" if strings.HasPrefix(str, "???") { str = tag } - tagStr += str - if i != lenTags-1 { + if InArray([]string{"red", "blue", "yellow", "green"}, tag) { + classes += " label-" + tag + } else { + classes += " label-default" + } + + classes += " label-post" + var url = tagPostUrl + "/" + url.QueryEscape(tag) + tagStr += "" + str + ""; + if i != lenTags - 1 { + tagStr += " " + } + } + return template.HTML(tagStr) + } + + // lea++ + revel.TemplateFuncs["blogTagsLea"] = func(renderArgs map[string]interface{}, tags []string, isRecommend bool) template.HTML { + if tags == nil || len(tags) == 0 { + return "" + } + locale, _ := renderArgs[revel.CurrentLocaleRenderArg].(string) + tagStr := "" + lenTags := len(tags) + + tagPostUrl := "http://lea.leanote.com/" + if isRecommend { + tagPostUrl += "?tag="; + } else { + tagPostUrl += "latest?tag="; + } + + for i, tag := range tags { + str := revel.Message(locale, tag) + var classes = "label" + if strings.HasPrefix(str, "???") { + str = tag + } + if InArray([]string{"red", "blue", "yellow", "green"}, tag) { + classes += " label-" + tag + } else { + classes += " label-default" + } + classes += " label-post" + var url = tagPostUrl + url.QueryEscape(tag) + tagStr += "" + str + ""; + if i != lenTags - 1 { + tagStr += " " + } + } + return template.HTML(tagStr) + } + + /* + revel.TemplateFuncs["blogTags"] = func(tags []string) template.HTML { + if tags == nil || len(tags) == 0 { + return "" + } + // TODO 这里判断语言, 从语言包中拿 + tagMap := map[string]string{"red": "红色", "yellow": "黄色", "blue": "蓝色", "green": "绿色"} + tagStr := "" + lenTags := len(tags) + for i, tag := range tags { + if text, ok := tagMap[tag]; ok { + tagStr += text + } else { + tagStr += tag + } + if i != lenTags - 1 { tagStr += "," } } return template.HTML(tagStr) } - /* - revel.TemplateFuncs["blogTags"] = func(tags []string) template.HTML { - if tags == nil || len(tags) == 0 { - return "" - } - // TODO 这里判断语言, 从语言包中拿 - tagMap := map[string]string{"red": "红色", "yellow": "黄色", "blue": "蓝色", "green": "绿色"} - tagStr := "" - lenTags := len(tags) - for i, tag := range tags { - if text, ok := tagMap[tag]; ok { - tagStr += text - } else { - tagStr += tag - } - if i != lenTags - 1 { - tagStr += "," - } - } - return template.HTML(tagStr) - } */ revel.TemplateFuncs["li"] = func(a string) string { return "" } // str连接 - revel.TemplateFuncs["urlConcat"] = func(url string, v ...interface{}) string { + revel.TemplateFuncs["urlConcat"] = func(url string, v... interface{}) string { html := "" for i := 0; i < len(v); i = i + 2 { item := v[i] if i+1 == len(v) { - break + break; } value := v[i+1] if item != nil && value != nil { - keyStr, _ := item.(string) - valueStr, err := value.(string) - if !err { - valueInt, _ := value.(int) - valueStr = strconv.Itoa(valueInt) - } - if keyStr != "" && valueStr != "" { - s := keyStr + "=" + valueStr - if html != "" { - html += "&" + s - } else { - html += s - } - } - } + keyStr, _ := item.(string) + valueStr, err := value.(string) + if !err { + valueInt, _ := value.(int) + valueStr = strconv.Itoa(valueInt) + } + if keyStr != "" && valueStr != "" { + s := keyStr + "=" + valueStr + if html != "" { + html += "&" + s + } else { + html += s + } + } + } } - + if html != "" { if strings.Index(url, "?") >= 0 { return url + "&" + html @@ -192,11 +242,11 @@ func init() { } return url } - + revel.TemplateFuncs["urlCond"] = func(url string, sorterI, keyords interface{}) template.HTML { return "" } - + // http://stackoverflow.com/questions/14226416/go-lang-templates-always-quotes-a-string-and-removes-comments revel.TemplateFuncs["rawMsg"] = func(renderArgs map[string]interface{}, message string, args ...interface{}) template.JS { str, ok := renderArgs[revel.CurrentLocaleRenderArg].(string) @@ -205,38 +255,38 @@ func init() { } return template.JS(revel.Message(str, message, args...)) } - + // 为后台管理sorter th使用 // 必须要返回HTMLAttr, 返回html, golang 会执行安全检查返回ZgotmplZ // sorterI 可能是nil, 所以用interfalce{}来接收 /* - data-url="/adminUser/index" - data-sorter="email" - class="th-sortable {{if eq .sorter "email-up"}}th-sort-up{{else}}{{if eq .sorter "email-down"}}th-sort-down{{end}}{{end}}" + data-url="/adminUser/index" + data-sorter="email" + class="th-sortable {{if eq .sorter "email-up"}}th-sort-up{{else}}{{if eq .sorter "email-down"}}th-sort-down{{end}}{{end}}" */ revel.TemplateFuncs["sorterTh"] = func(url, sorterField string, sorterI interface{}) template.HTMLAttr { sorter := "" if sorterI != nil { sorter, _ = sorterI.(string) } - html := "data-url=\"" + url + "\" data-sorter=\"" + sorterField + "\"" - html += " class=\"th-sortable " - if sorter == sorterField+"-up" { - html += "th-sort-up\"" - } else if sorter == sorterField+"-down" { - html += "th-sort-down" + html := "data-url=\"" + url + "\" data-sorter=\"" + sorterField + "\""; + html += " class=\"th-sortable "; + if sorter == sorterField + "-up" { + html += "th-sort-up\""; + } else if(sorter == sorterField + "-down") { + html += "th-sort-down"; } - html += "\"" + html += "\""; return template.HTMLAttr(html) } - + // pagination revel.TemplateFuncs["page"] = func(urlBase string, page, pageSize, count int) template.HTML { if count == 0 { - return "" + return ""; } - totalPage := int(math.Ceil(float64(count) / float64(pageSize))) - + totalPage := int(math.Ceil(float64(count)/float64(pageSize))) + preClass := "" prePage := page - 1 if prePage == 0 { @@ -245,10 +295,10 @@ func init() { nextClass := "" nextPage := page + 1 var preUrl, nextUrl string - - preUrl = urlBase + "?page=" + strconv.Itoa(prePage) + + preUrl = urlBase + "?page=" + strconv.Itoa(prePage) nextUrl = urlBase + "?page=" + strconv.Itoa(nextPage) - + // 没有上一页了 if page == 1 { preClass = "disabled" @@ -266,53 +316,53 @@ func init() { // http://play.golang.org/p/snygrVpQva // http://grokbase.com/t/gg/golang-nuts/142a6dhfh3/go-nuts-text-template-using-comparison-operators-eq-gt-etc-on-non-existent-variable-causes-the-template-to-stop-outputting-but-with-no-error-correct-behaviour /* - revel.TemplateFuncs["gt"] = func(a1, a2 interface{}) bool { - switch a1.(type) { + revel.TemplateFuncs["gt"] = func(a1, a2 interface{}) bool { + switch a1.(type) { + case string: + switch a2.(type) { case string: - switch a2.(type) { - case string: - return reflect.ValueOf(a1).String() > reflect.ValueOf(a2).String() - } + return reflect.ValueOf(a1).String() > reflect.ValueOf(a2).String() + } + case int, int8, int16, int32, int64: + switch a2.(type) { case int, int8, int16, int32, int64: - switch a2.(type) { - case int, int8, int16, int32, int64: - return reflect.ValueOf(a1).Int() > reflect.ValueOf(a2).Int() - } + return reflect.ValueOf(a1).Int() > reflect.ValueOf(a2).Int() + } + case uint, uint8, uint16, uint32, uint64: + switch a2.(type) { case uint, uint8, uint16, uint32, uint64: - switch a2.(type) { - case uint, uint8, uint16, uint32, uint64: - return reflect.ValueOf(a1).Uint() > reflect.ValueOf(a2).Uint() - } + return reflect.ValueOf(a1).Uint() > reflect.ValueOf(a2).Uint() + } + case float32, float64: + switch a2.(type) { case float32, float64: - switch a2.(type) { - case float32, float64: - return reflect.ValueOf(a1).Float() > reflect.ValueOf(a2).Float() - } + return reflect.ValueOf(a1).Float() > reflect.ValueOf(a2).Float() } - return false } - */ - - /* - {{range $i := N 1 10}} -
{{$i}}
- {{end}} - */ - revel.TemplateFuncs["N"] = func(start, end int) (stream chan int) { - stream = make(chan int) - go func() { - for i := start; i <= end; i++ { - stream <- i - } - close(stream) - }() - return + return false } - + */ + + /* + {{range $i := N 1 10}} +
{{$i}}
+ {{end}} + */ + revel.TemplateFuncs["N"] = func(start, end int) (stream chan int) { + stream = make(chan int) + go func() { + for i := start; i <= end; i++ { + stream <- i + } + close(stream) + }() + return + } + // init Email revel.OnAppStart(func() { // 数据库 - db.Init() + db.Init("", "") // email配置 InitEmail() InitVd() @@ -323,5 +373,5 @@ func init() { admin.InitService() member.InitService() service.ConfigS.InitGlobalConfigs() - }) -} + }); +} \ No newline at end of file diff --git a/app/lea/Debug.go b/app/lea/Debug.go index ce8bb02..7684521 100644 --- a/app/lea/Debug.go +++ b/app/lea/Debug.go @@ -3,6 +3,7 @@ package lea import ( "encoding/json" "github.com/revel/revel" + "fmt" ) func Log(i interface{}) { @@ -12,4 +13,14 @@ func Log(i interface{}) { func LogJ(i interface{}) { b, _ := json.MarshalIndent(i, "", " ") revel.INFO.Println(string(b)) -} \ No newline at end of file +} + +// 为test用 +func L(i interface{}) { + fmt.Println(i) +} + +func LJ(i interface{}) { + b, _ := json.MarshalIndent(i, "", " ") + fmt.Println(string(b)) +} diff --git a/app/release/release.go b/app/release/release.go index 05c0d2b..d02621d 100644 --- a/app/release/release.go +++ b/app/release/release.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "strings" ) + /* 用golang exec 总是说找不到uglifyjs命令, 需要全部路径 而且node, npm要在/usr/bin下, 已建ln @@ -31,7 +32,7 @@ import ( //var jss = []string{"js/jquery-cookie", "js/bootstrap"} var jss = []string{"js/jquery-cookie", "js/bootstrap", "js/common", "js/app/note", "js/app/tag", "js/app/notebook", "js/app/share", - "js/object_id", "js/ZeroClipboard/ZeroClipboard"} + "js/object_id"} var base1 = "/Users/life/Documents/Go/package2/src/github.com/leanote/leanote/" var base = "/Users/life/Documents/Go/package2/src/github.com/leanote/leanote/public/" @@ -52,7 +53,7 @@ func compressJs(filename string) { to := base + filename + "-min.js" cmd := exec.Command(cmdPath, source, "-o", to) _, err := cmd.CombinedOutput() - + fmt.Println(source); cmdError(err) } @@ -80,7 +81,10 @@ func combineJs() { // 改note-dev->note func dev() { // 即替换note.js->note-min.js - m := map[string]string{"note.js": "note-min.js", + m := map[string]string{"tinymce.dev.js": "tinymce.min.js", + "tinymce.js": "tinymce.min.js", + "jquery.ztree.all-3.5.js": "jquery.ztree.all-3.5-min.js", + "note.js": "note-min.js", "app.js": "app-min.js", "page.js": "page-min.js", "common.js": "common-min.js", @@ -88,6 +92,7 @@ func dev() { "share.js": "share-min.js", "tag.js": "tag-min.js", "main.js": "main-min.js", + "jquery.slimscroll.js": "jquery.slimscroll-min.js", "jquery.contextmenu.js": "jquery.contextmenu-min.js", "editor/editor.js": "editor/editor-min.js", "/public/mdeditor/editor/scrollLink.js": "/public/mdeditor/editor/scrollLink-min.js", @@ -111,12 +116,21 @@ func tinymce() { // cmd := exec.Command("/Users/life/Documents/eclipse-workspace/go/leanote_release/tinymce-master/node_modules/jake/bin/cli.js", "minify", "bundle[themes:modern,plugins:table,paste,advlist,autolink,link,image,lists,charmap,hr,searchreplace,visualblocks,visualchars,code,nav,tabfocus,contextmenu,directionality,codemirror,codesyntax,textcolor,fullpage]") cmd := exec.Command("/Users/life/Documents/eclipse-workspace/go/leanote_release/tinymce-master/node_modules/jake/bin/cli.js", "minify") cmd.Dir = "/Users/life/Documents/eclipse-workspace/go/leanote_release/tinymce-master" - c, err := cmd.CombinedOutput() + + // 必须要先删除 + cmd2 := exec.Command("/bin/sh", "-c", "rm " + cmd.Dir + "/js/tinymce/tinymce.dev.js") + cmd2.CombinedOutput() + cmd2 = exec.Command("/bin/sh", "-c", "rm " + cmd.Dir + "/js/tinymce/tinymce.jquery.dev.js") + c, _ := cmd2.CombinedOutput() + fmt.Println(string(c)) + c, _ = cmd.CombinedOutput() fmt.Println(string(c)) - cmdError(err) } func main() { + // 压缩tinymce + tinymce() + dev(); // 其它零散的需要压缩的js @@ -133,6 +147,10 @@ func main() { "mdeditor/editor/underscore", "mdeditor/editor/mathJax", "js/jQuery-slimScroll-1.3.0/jquery.slimscroll", + "js/app/editor_drop_paste", + "js/app/attachment_upload", + "js/jquery.ztree.all-3.5", + "js/jQuery-slimScroll-1.3.0/jquery.slimscroll", } for _, js := range otherJss { @@ -141,7 +159,5 @@ func main() { // 先压缩后合并 combineJs() - - // 压缩tinymce - tinymce() + } diff --git a/app/service/AttachService.go b/app/service/AttachService.go index 521558d..27a0e16 100644 --- a/app/service/AttachService.go +++ b/app/service/AttachService.go @@ -15,16 +15,16 @@ type AttachService struct { } // add attach -func (this *AttachService) AddAttach(attach info.Attach) bool { +func (this *AttachService) AddAttach(attach info.Attach) (ok bool, msg string) { attach.CreatedTime = time.Now() - ok := db.Insert(db.Attachs, attach) + ok = db.Insert(db.Attachs, attach) if ok { // 更新笔记的attachs num this.updateNoteAttachNum(attach.NoteId, 1) } - return ok + return } // 更新笔记的附件个数 diff --git a/app/service/AuthService.go b/app/service/AuthService.go index 6e4fd24..3937741 100644 --- a/app/service/AuthService.go +++ b/app/service/AuthService.go @@ -5,6 +5,7 @@ import ( // "github.com/leanote/leanote/app/db" "github.com/leanote/leanote/app/info" // "github.com/revel/revel" + "strings" . "github.com/leanote/leanote/app/lea" "fmt" "strconv" @@ -17,6 +18,8 @@ type AuthService struct { // pwd已md5了 func (this *AuthService) Login(emailOrUsername, pwd string) info.User { + emailOrUsername = strings.Trim(emailOrUsername, " ") +// pwd = strings.Trim(pwd, " ") userInfo := userService.LoginGetUserInfo(emailOrUsername, Md5(pwd)) return userInfo } @@ -32,12 +35,16 @@ func (this *AuthService) Login(emailOrUsername, pwd string) info.User { // 1. 添加用户 // 2. 将leanote共享给我 // [ok] -func (this *AuthService) Register(email, pwd string) (bool, string) { +func (this *AuthService) Register(email, pwd, fromUserId string) (bool, string) { // 用户是否已存在 if userService.IsExistsUser(email) { return false, "userHasBeenRegistered-" + email } user := info.User{UserId: bson.NewObjectId(), Email: email, Username: email, Pwd: Md5(pwd)} + if fromUserId != "" && IsObjectId(fromUserId) { + user.FromUserId = bson.ObjectIdHex(fromUserId) + } + LogJ(user) return this.register(user) } @@ -129,4 +136,4 @@ func (this *AuthService) ThirdRegister(thirdType, thirdUserId, thirdUsername str } _, _ = this.register(userInfo) return -} \ No newline at end of file +} diff --git a/app/service/FileService.go b/app/service/FileService.go index 21a2e5e..d335db7 100644 --- a/app/service/FileService.go +++ b/app/service/FileService.go @@ -17,7 +17,7 @@ type FileService struct { } // add Image -func (this *FileService) AddImage(image info.File, albumId, userId string) bool { +func (this *FileService) AddImage(image info.File, albumId, userId string, needCheckSize bool) (ok bool, msg string) { image.CreatedTime = time.Now() if albumId != "" { image.AlbumId = bson.ObjectIdHex(albumId) @@ -27,7 +27,8 @@ func (this *FileService) AddImage(image info.File, albumId, userId string) bool } image.UserId = bson.ObjectIdHex(userId) - return db.Insert(db.Files, image) + ok = db.Insert(db.Files, image) + return } // list images @@ -147,7 +148,16 @@ func (this *FileService) GetFile(userId, fileId string) string { return path } + // 2014/12/28 修复, 如果是分享给用户组, 那就不行, 这里可以实现 + for _, noteId := range noteIds { + note := noteService.GetNoteById(noteId.Hex()) + if shareService.HasReadPerm(note.UserId.Hex(), userId, noteId.Hex()) { + return path; + } + } + /* // 若有共享给我的笔记? + // 对该笔记可读? if db.Has(db.ShareNotes, bson.M{"ToUserId": bson.ObjectIdHex(userId), "NoteId": bson.M{"$in": noteIds}}) { return path } @@ -166,6 +176,7 @@ func (this *FileService) GetFile(userId, fileId string) string { return path } } + */ } // 可能是刚复制到owner上, 但内容又没有保存, 所以没有note->imageId的映射, 此时看是否有fromFileId @@ -222,7 +233,7 @@ func (this *FileService) CopyImage(userId, fileId, toUserId string) (bool, strin id := bson.NewObjectId(); fileInfo.FileId = id fileId = id.Hex() - Ok := this.AddImage(fileInfo, "", toUserId) + Ok, _ := this.AddImage(fileInfo, "", toUserId, false) if Ok { return Ok, id.Hex() diff --git a/app/service/GroupService.go b/app/service/GroupService.go index 3dfc273..89c370c 100644 --- a/app/service/GroupService.go +++ b/app/service/GroupService.go @@ -27,9 +27,12 @@ func (this *GroupService) AddGroup(userId, title string) (bool, info.Group) { // 删除分组 // 判断是否有好友 func (this *GroupService) DeleteGroup(userId, groupId string) (ok bool, msg string) { + /* if db.Has(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}) { - return false, "hasUsers" + return false, "groupHasUsers" } + */ + db.DeleteAll(db.GroupUsers, bson.M{"GroupId": bson.ObjectIdHex(groupId)}) return db.DeleteByIdAndUserId(db.Groups, groupId, userId), "" // TODO 删除分组后, 在shareNote, shareNotebook中也要删除 diff --git a/app/service/NoteContentHistoryService.go b/app/service/NoteContentHistoryService.go index 4b67c31..803feb6 100644 --- a/app/service/NoteContentHistoryService.go +++ b/app/service/NoteContentHistoryService.go @@ -33,7 +33,8 @@ func (this *NoteContentHistoryService) AddHistory(noteId, userId string, eachHis // TODO l := len(history.Histories) if l >= maxSize { - history.Histories = history.Histories[l-maxSize:] + // history.Histories = history.Histories[l-maxSize:] // BUG, 致使都是以前的 + history.Histories = history.Histories[:maxSize] } newHistory := []info.EachHistory{eachHistory} newHistory = append(newHistory, history.Histories...) // 在开头加了, 最近的在最前 @@ -61,4 +62,4 @@ func (this *NoteContentHistoryService) ListHistories(noteId, userId string) []in histories := info.NoteContentHistory{} db.GetByIdAndUserId(db.NoteContentHistories, noteId, userId, &histories) return histories.Histories -} \ No newline at end of file +} diff --git a/app/service/ShareService.go b/app/service/ShareService.go index e8ed5f1..74bb2db 100644 --- a/app/service/ShareService.go +++ b/app/service/ShareService.go @@ -50,6 +50,7 @@ func (this *ShareService) getOrQ(userId string) bson.M { return q } +// 得到共享给我的笔记本和用户(谁共享给了我) func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksByUser, []info.User) { // 得到共享给我的用户s信息 // 得到我参与的组织 @@ -61,7 +62,7 @@ func (this *ShareService) GetShareNotebooks(userId string) (info.ShareNotebooksB db.Distinct(db.ShareNotes, q, "UserId", &userIds1) userIds2 := []bson.ObjectId{} - db.Distinct(db.ShareNotebooks, q, "UserId", &userIds1) + db.Distinct(db.ShareNotebooks, q, "UserId", &userIds2) // BUG之前是userId1, 2014/12/29 userIds := append(userIds1, userIds2...) userInfos := userService.GetUserInfosOrderBySeq(userIds); diff --git a/app/service/ThemeService.go b/app/service/ThemeService.go index 95577a7..0867299 100644 --- a/app/service/ThemeService.go +++ b/app/service/ThemeService.go @@ -13,6 +13,7 @@ import ( "fmt" "html/template" "regexp" + "io/ioutil" "encoding/json" ) @@ -127,7 +128,8 @@ func (this *ThemeService) CopyDefaultTheme(userBlog info.UserBlog) (ok bool, the // 设为active true func (this *ThemeService) NewThemeForFirst(userBlog info.UserBlog) (ok bool, themeId string) { ok, themeId = this.CopyDefaultTheme(userBlog) - db.UpdateByQField(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId)}, "IsActive", true) + this.ActiveTheme(userBlog.UserId.Hex(), themeId) + // db.UpdateByQField(db.Themes, bson.M{"_id": bson.ObjectIdHex(themeId)}, "IsActive", true) return } @@ -285,11 +287,15 @@ func (this *ThemeService) GetThemePath(userId, themeId string) string { } // 更新模板内容 func (this *ThemeService) UpdateTplContent(userId, themeId, filename, content string) (ok bool, msg string) { - path := this.GetThemeAbsolutePath(userId, themeId) + "/" + filename + basePath := this.GetThemeAbsolutePath(userId, themeId) + path := basePath + "/" + filename if strings.Contains(filename, ".html") { - // 模板 - if ok, msg = this.mustTpl(filename, content); ok { - ok = PutFileStrContent(path, content) + Log(">>") + if ok, msg = this.ValidateTheme(basePath, filename, content); ok { + // 模板 + if ok, msg = this.mustTpl(filename, content); ok { + ok = PutFileStrContent(path, content) + } } return } else if filename == "theme.json" { @@ -410,6 +416,11 @@ func (this *ThemeService) ImportTheme(userId, path string) (ok bool, msg string) DeleteFile(targetPath) return } + // 主题验证 + if ok, msg = this.ValidateTheme(targetPath, "", ""); !ok { + DeleteFile(targetPath) + return + } // 解压成功, 那么新建之 // 保存到数据库中 theme, _ := this.getThemeConfig(targetPath) @@ -505,5 +516,119 @@ func (this *ThemeService) InstallTheme(userId, themeId string) (ok bool) { ok = db.Insert(db.Themes, theme) + // 激活之 + this.ActiveTheme(userId, themeId); + return ok } + +// 验证主题是否全法, 存在循环引用? +// filename, newContent 表示在修改模板时要判断模板修改时是否有错误 +func (this *ThemeService) ValidateTheme(path string, filename, newContent string) (ok bool, msg string) { + Log("theme Path") + Log(path) + // 建立一个有向图 + // 将该path下的所有文件提出, 得到文件的引用情况 + files := ListDir(path) + LogJ(files); + size := len(files) + if(size > 100) { + ok = false; + msg = "tooManyFiles" + return + } + /* + 111111111 + 111000000 + */ + vector := make([][]int, size) + for i := 0; i < size; i++ { + vector[i] = make([]int, size) + } + fileIndexMap := map[string]int{} // fileName => index + fileContent := map[string]string{} // fileName => content + index := 0 + // 得到文件内容, 和建立索引, 每个文件都有一个index, 对应数组位置 + for _, t := range files { + if !strings.Contains(t, ".html") { + continue; + } + if t != filename { + fileBytes, err := ioutil.ReadFile(path + "/" + t) + if err != nil { + continue + } + + fileIndexMap[t] = index; + // html内容 + fileStr := string(fileBytes) + fileContent[t] = fileStr + } else { + fileIndexMap[t] = index + fileContent[t] = newContent + } + index++ + } + // 分析文件内容, 建立有向图 + reg, _ := regexp.Compile("{{ *template \"(.+?\\.html)\".*}}") + for filename, content := range fileContent { + thisIndex := fileIndexMap[filename] + finds := reg.FindAllStringSubmatch(content, -1) // 子匹配 + LogJ(finds) +// Log(content) + if finds != nil && len(finds) > 0 { + for _, includes := range finds { + include := includes[1] + includeIndex, has := fileIndexMap[include] + Log(includeIndex) + Log("??") + Log(has) + if has { + vector[thisIndex][includeIndex] = 1 + } + } + } + } + + LogJ(vector) + LogJ(fileIndexMap) + // 建立图后, 判断是否有环 + if this.hasRound(vector, index) { + ok = false + msg = "themeValidHasRoundInclude" + } else { + ok = true + } + return; +} + +// 检测有向图是否有环, DFS +func (this *ThemeService) hasRound(vector [][]int, size int) (ok bool) { + for i := 0; i < size; i++ { + visited := make([]int, size) + if this.hasRoundEach(vector, i, size, visited) { + Log(">>") + Log(i); + return true; + } + } + return false +} + +// 从每个节点出发, 判断是否有环 +func (this *ThemeService) hasRoundEach(vector [][]int, index int, size int, visited []int) (ok bool) { + if visited[index] > 0 { + Log("<") + Log(index) + return true + } + visited[index] = 1; + // 遍历它的孩子 + for i := 0; i < size; i++ { + if vector[index][i] > 0 { + return this.hasRoundEach(vector, i, size, visited); + } + } + visited[index] = 0; + return false; +} diff --git a/app/service/UserService.go b/app/service/UserService.go index 851d1b8..350d5da 100644 --- a/app/service/UserService.go +++ b/app/service/UserService.go @@ -376,7 +376,7 @@ func (this *UserService) ThirdAddUser(userId, email, pwd string) (ok bool, msg s // 宽度 func (this *UserService)UpdateColumnWidth(userId string, notebookWidth, noteListWidth, mdEditorWidth int) bool { return db.UpdateByQMap(db.Users, bson.M{"_id": bson.ObjectIdHex(userId)}, - bson.M{"NotebookWidth": notebookWidth, "NoteListWidth": noteListWidth, "mdEditorWidth": mdEditorWidth}) + bson.M{"NotebookWidth": notebookWidth, "NoteListWidth": noteListWidth, "MdEditorWidth": mdEditorWidth}) } // 左侧是否隐藏 func (this *UserService)UpdateLeftIsMin(userId string, leftIsMin bool) bool { diff --git a/app/views/admin/top.html b/app/views/admin/top.html index aaff7da..8948162 100644 --- a/app/views/admin/top.html +++ b/app/views/admin/top.html @@ -84,7 +84,7 @@