public async Task <JsonResult> EditTag(string TagToAdd, int[] TagToDel, int BlogID) { var TagsToAdd = TagUtil.SplitTags(TagToAdd); if (TagsToAdd.Any(t => t.Length > 20)) { return(Json(new { errmsg = "标签不得超过20字符" })); } else { Blog b = _db.Blogs.Find(BlogID); if (b == null || BlogID <= 0 || (b.option != null && b.option.LockTags)) { return(Json(new { errmsg = "无效id,请刷新重试" })); } var tibs = await _db.TagsInBlogs.Include(tib => tib.tag).Where(t => t.BlogID == BlogID).ToListAsync(); // Remove TagToAdd items from TagsToDel var TagsToDel = TagToDel == null ? new TagsInBlog[0] : tibs.Where(tib => TagToDel.Contains(tib.TagID) && !TagsToAdd.Contains(tib.tag.TagName, SqlStringComparer.Instance)).ToArray(); // Remove already exist tags from TagsToAdd TagsToAdd = TagsToAdd.Where(s => tibs.All(tib => !SqlStringComparer.Instance.Equals(tib.tag.TagName, s))).ToArray(); if (tibs.Any(tib => !tib.IsRemovable(b.Author, User.Identity.Name, _blogUtil.CheckAdmin(), HarmonySettings.BlacklistTags) && TagToDel.Contains(tib.TagID))) { return(Json(new { errmsg = "您不能删除作者添加的或黑名单标签" })); } if (tibs.Count + TagsToAdd.Length - TagsToDel.Length > 10) { return(Json(new { errmsg = "标签不得超过10个" })); } else if (tibs.Count + TagsToAdd.Length - TagsToDel.Length < 1) { return(Json(new { errmsg = "请至少添加一个标签" })); } List <Tag> AddedTags = _tagUtil.AddTagsForBlog(BlogID, TagsToAdd, User.Identity.Name); _db.TagHistories.AddRange(TagsToDel.Select(tib => new TagHistory { AddBy = tib.AddBy, BlogID = BlogID, DeleteBy = User.Identity.Name, TagName = tib.tag.TagName, Time = DateTime.Now })); _db.TagsInBlogs.RemoveRange(TagsToDel); bool isHarmony = BlogHelper.BlogIsHarmony(_db, b, HarmonySettings); if (isHarmony != b.isHarmony) { b.isHarmony = isHarmony; _cacheService.ClearHPCache(this, null); } await _db.SaveChangesAsync(); var currentTags = tibs.Except(TagsToDel).Select(tib => tib.tag).Concat(AddedTags).OrderBy(t => t.TagName); TriggerEditTags(b, currentTags); return(Json(AddedTags.ToDictionary(t => t.TagID.ToString(), t => t.TagName))); } }
public async Task <PartialViewResult> HPSetting(HPSettingsModel model) { string option, tagBlacklist = null; var allCategories = _catUtil.GetCategoryList(); var categories = model.GetCategoryOptions(); if (categories.SelectedIds.Count == 0 || (allCategories.Count == categories.SelectedIds.Count)) { option = string.Empty; } else { option = JsonConvert.SerializeObject(categories.SelectedIds); } if (!string.IsNullOrWhiteSpace(model.BlacklistTagNames)) { var taglist = TagUtil.SplitTags(model.BlacklistTagNames); if (taglist != null && taglist.Length > 0) { var tags = await _bdb.Tags.Where(t => taglist.Contains(t.TagName)).ToDictionaryAsync(t => t.TagName.ToLower(), t => t.TagID); var notfound = taglist.Where(n => !tags.ContainsKey(n.ToLower())); if (notfound.Any()) { ViewBag.NotFoundTags = string.Join(",", notfound); ViewBag.Success = false; return(PartialView("_HPSettingPartial", model)); } tagBlacklist = JsonConvert.SerializeObject(tags.Values.AsEnumerable()); } } UserProfile user = _db.Users.Include("option").SingleOrDefault(u => u.UserName == User.Identity.Name); if (user.option == null) { user.option = new UserOption(); } user.option.homepageCategories = option; user.option.homepageHideHarmony = model.HideHarmony; user.option.homepageTagBlacklist = tagBlacklist; _blogUtil.CacheUserOption(user.option, User.Identity.Name); await _db.SaveChangesAsync(); ViewBag.Success = true; return(PartialView("_HPSettingPartial", model)); }
public async Task <ActionResult> Edit([FromServices] HtmlSanitizerService sanitizerService, int id, BlogEdit blog, IFormFile[] files, bool setmain = false) { ViewBag.CategoryList = _catUtil.GetCategoryDropdown(blog.CategoryID); ViewBag.id = id; if (NolinkCategories == null || !NolinkCategories.Contains(blog.CategoryID)) { if (blog.BlogLinks == null) { ModelState.AddModelError("", "链接地址不能为空"); return(View(blog)); } else { blog.BlogLinks = blog.BlogLinks.Where(b => !string.IsNullOrWhiteSpace(b.url)).ToArray(); if (!BlogHelper.checkBlogLinks(blog.BlogLinks)) { ModelState.AddModelError("", "链接地址不能为空,且不得包含javascript"); return(View(blog)); } } } if (blog.Content == null || string.IsNullOrWhiteSpace(BlogHelper.removeAllTags(blog.Content))) { ModelState.AddModelError("", "内容不能为空或纯图片"); return(View(blog)); } if (!_blogUtil.CheckAdmin()) { blog.Content = sanitizerService.Sanitize(blog.Content); } if (ModelState.IsValid) { Blog originalblog = _db.Blogs.Find(id); bool hasupload = false; List <string> dellist = null; List <string> newlist = null; string thumb = null; string newthumb = null; string[] originalImglist = originalblog.ImagePath?.Split(';') ?? new string[] { }; string[] currentImglist = blog.ImagePath?.Split(';') ?? new string[] { }; int imgcount = currentImglist.Length; bool[] uploadpos = null; if (originalblog.option != null) { originalblog.option.MergeWith(_blogUtil, blog.Option); } else if (!blog.Option.OverrideOption(_blogUtil).IsDefault()) { originalblog.option = blog.Option; } if (originalblog.IsLocalImg) { dellist = originalImglist.ToList(); thumb = dellist.First(); } if (currentImglist.Length != 0) //item has local image & might or might not changed { // foreach name in current imglist, if orignal imglist does not contain the name,it is not valid if (!currentImglist.All(n => originalImglist.Contains(n))) { ModelState.AddModelError("", "内部参数错误,请刷新重试"); return(View(blog)); } // foreach name in orignial imglist, if current imglist does not contain the name,delete it dellist = originalImglist.Except(currentImglist).ToList(); originalblog.ImagePath = blog.ImagePath; } if (files != null) { uploadpos = new bool[files.Length]; imgcount += files.Where(f => f != null).Count(); for (int i = 0; i < files.Length; i++) { var data = files[i]; if (data != null) { if (data.Length > 1048576 * 4 || !data.ContentType.Contains("image")) { ModelState.AddModelError("", "单个文件不得超过4MB,且必须是图片"); return(View(blog)); } hasupload = true; uploadpos[i] = true; } else { uploadpos[i] = false; } } } if (hasupload) // has upload file { try { newlist = await _uploadUtil.SaveImagesAsync(files, false); } catch (Exception e) { ModelState.AddModelError("", "保存图片时发生异常:(" + e.Message + ")。如多次出错,请汇报给管理员。"); return(View(blog)); } if (newlist.Count < 1) { ModelState.AddModelError("", "图片服务器上传出错,请稍后再试。如多次出错,请汇报给管理员。"); return(View(blog)); } int i = 0; if (originalblog.IsLocalImg && setmain && files[0] != null && currentImglist.Length > 0) { List <string> updatedImgList = new List <string>(currentImglist); updatedImgList.Insert(0, newlist[0]); updatedImgList.AddRange(newlist.Skip(1)); originalblog.ImagePath = string.Join(";", updatedImgList); blog.Content = BlogHelper.InsertImgPlaceholder(blog.Content); i++; } else if (!originalblog.IsLocalImg) { originalblog.ImagePath = string.Join(";", newlist); } else { originalblog.ImagePath = string.Join(";", currentImglist.Concat(newlist)); } blog.Content = BlogHelper.ReplaceNewImgPlaceholder(blog.Content, i, currentImglist.Length, uploadpos); originalblog.IsLocalImg = true; } if (!originalblog.IsLocalImg || imgcount == 0) //no img no upload { string imgname = BlogHelper.getFirstImg(blog.Content); if (imgname == null || imgname.Length < 5) { ModelState.AddModelError("", "请添加预览图!(上传或外链图片)"); blog.ImagePath = originalblog.ImagePath; return(View(blog)); } originalblog.ImagePath = imgname; originalblog.IsLocalImg = false; } else { newthumb = originalblog.ImagePath.Split(';').ToList().First(); } var mention = new MentionHandler(_udb); blog.Content = mention.ParseMentions(blog.Content); mention.SendMentionMsg(_msgUtil, originalblog.Author, originalblog.BlogTitle, Url.Action("Details", new { id = originalblog.BlogID })); if (blog.Option != null && (originalblog.option != null || !blog.Option.IsDefault())) { originalblog.option = blog.Option; } // else image uploaded before and did not changed string[] tags = TagUtil.SplitTags(blog.BlogTags); List <Tag> updatedTags = null; try { // Replace 【】() with []() originalblog.BlogTitle = blog.BlogTitle.ToSingleByteCharacterString(); originalblog.Content = BlogHelper.RemoveComments(blog.Content); originalblog.CategoryID = blog.CategoryID; originalblog.Links = Newtonsoft.Json.JsonConvert.SerializeObject(blog.BlogLinks); if (blog.Option.NoApprove) { originalblog.isApproved = false; } else if (originalblog.isApproved == false) { originalblog.isApproved = null; } else if (originalblog.isApproved == null) { // Remove pending votes since the blog has changed. var audits = _db.BlogAudits.Where(b => b.BlogID == originalblog.BlogID).ToList(); var lastDecision = audits.Where(ba => ba.AuditAction == BlogAudit.Action.Approve || ba.AuditAction == BlogAudit.Action.Deny).OrderByDescending(ba => ba.BlogVersion).FirstOrDefault(); int lastVersion = lastDecision == null ? 0 : lastDecision.BlogVersion; _db.BlogAudits.RemoveRange(audits.Where(ba => ba.BlogVersion > lastVersion && (ba.AuditAction == BlogAudit.Action.VoteApprove || ba.AuditAction == BlogAudit.Action.VoteDeny))); } updatedTags = _tagUtil.SetTagsForBlog(originalblog.BlogID, tags, originalblog.Author); originalblog.isHarmony = BlogHelper.BlogIsHarmony(_db, originalblog, HarmonySettings); _db.SaveChanges(); } catch { if (originalblog.IsLocalImg && newlist != null) { await _uploadUtil.DeleteFilesAsync(newlist); } throw; } if (dellist != null && dellist.Count > 0) { await _uploadUtil.DeleteFilesAsync(dellist); } if (thumb != null && thumb != newthumb && blog.IsLocalImg) { await _uploadUtil.DeleteFileAsync(thumb.Replace("/upload/", "/thumbs/")); } if (originalblog.IsLocalImg && thumb != newthumb) { await _uploadUtil.SaveThumbAsync(originalblog.ImagePath); } if (originalblog.Author != User.Identity.Name) { _adminUtil.log(User.Identity.Name, "editblog", originalblog.BlogID.ToString()); } TriggerEditBlog(originalblog, updatedTags); return(RedirectToAction("Details", new { id })); } return(View(blog)); }
public async Task <ActionResult> Create(BlogEdit blog, [FromServices] HtmlSanitizerService sanitizerService) { ViewBag.CategoryList = _catUtil.GetCategoryDropdown(); ViewBag.UserHanGroup = GetUserHanGroup(); string content = blog.Content; bool isLocalimg = false; Blog newblog; List <string> imglist = null; try { if (!ModelState.IsValid) { throw new BlogException(); } if (content == null || string.IsNullOrWhiteSpace(BlogHelper.removeAllTags(content))) { ModelState.AddModelError("", "内容不能为空或纯图片"); throw new BlogException(); } if (NolinkCategories == null || !NolinkCategories.Contains(blog.CategoryID)) { if (blog.BlogLinks == null) { ModelState.AddModelError("", "链接地址不能为空"); throw new BlogException(); } else { blog.BlogLinks = blog.BlogLinks.Where(b => !string.IsNullOrWhiteSpace(b.url)).ToArray(); if (!BlogHelper.checkBlogLinks(blog.BlogLinks)) { ModelState.AddModelError("", "链接地址不能为空,且不得包含javascript"); throw new BlogException(); } } } if (!_blogUtil.CheckAdmin()) { content = sanitizerService.Sanitize(content); } if (blog.HanGroupID.HasValue && !_db.HanGroupMembers.Any(h => h.Username == User.Identity.Name && h.HanGroupID == blog.HanGroupID)) { ModelState.AddModelError("", "汉化组ID无效,请刷新重试。"); throw new BlogException(); } List <IFormFile> BlogImages = new List <IFormFile>(); if (Request.Form.Files.Count > 0) { for (int i = 0; i < Request.Form.Files.Count; i++) { var file = Request.Form.Files[i]; if (file.Length > 0) { if (!file.ContentType.Contains("image")) { ModelState.AddModelError("", "不接受的文件类型"); throw new BlogException(); } else if (file.Length > 1048576 * 4) { ModelState.AddModelError("", "文件不得超过4MB"); throw new BlogException(); } isLocalimg = true; BlogImages.Add(file); } else { content = BlogHelper.removeImgPlaceholder(content, i); } } } if (!isLocalimg) { var imgname = BlogHelper.getFirstImg(content); if (imgname == null || imgname.Length < 5) { ModelState.AddModelError("", "请添加预览图!(上传或在文中外链图片)"); throw new BlogException(); } imglist = new List <string>() { imgname }; } else { try { imglist = await _uploadUtil.SaveImagesAsync(BlogImages); } catch (Exception e) { ModelState.AddModelError("", "保存图片时发生异常:(" + e.Message + ")。如多次出错,请汇报给管理员。"); throw new BlogException(e.Message, e); } if (imglist.Count < 1) { ModelState.AddModelError("", "图片服务器上传出错,请稍后再试。如多次出错,请汇报给管理员。"); throw new BlogException(); } } string imgpath = string.Empty; if (imglist != null) { imgpath = string.Join(";", imglist); } bool approve = User.IsInRole("Administrator") || User.IsInRole("Writers") || User.IsInRole("Moderator"); // Replace 【】() with []() blog.BlogTitle = blog.BlogTitle.ToSingleByteCharacterString(); blog.ImagePath = imgpath; content = BlogHelper.RemoveComments(content); newblog = _blogUtil.AddBlog(blog.BlogTitle, content, blog.CategoryID, imgpath, User.Identity.Name, approve, isLocalimg, blog.BlogLinks); var taglist = new List <Tag>(); if (!string.IsNullOrEmpty(blog.BlogTags)) { string[] tags = TagUtil.SplitTags(blog.BlogTags); taglist = _tagUtil.AddTagsForBlog(newblog.BlogID, tags, newblog.Author); } var save = false; if (BlogHelper.BlogIsHarmony(_db, newblog, HarmonySettings)) { newblog.isHarmony = true; save = true; } if (blog.HanGroupID.HasValue) { _db.HanGroupBlogs.Add(new HanGroupBlog { BlogID = newblog.BlogID, HanGroupID = blog.HanGroupID.Value }); save = true; } if (blog.Option != null && !blog.Option.IsDefault()) { newblog.option = blog.Option.OverrideOption(_blogUtil); if (newblog.option.NoApprove) { newblog.isApproved = false; } save = true; } if (save) { _db.SaveChanges(); } TriggerNewBlog(newblog, taglist); } catch (BlogException e) { if (Request.IsAjaxRequest()) { return(Json(new { err = e.Message + string.Join(";", ModelState.Values.SelectMany(m => m.Errors) .Select(err => err.ErrorMessage) .ToList()) })); } return(View(blog)); } catch { if (isLocalimg && imglist != null) { await _uploadUtil.DeleteFilesAsync(imglist.Concat(new[] { blog.ImagePath.Split(';')[0].Replace("/upload/", "/thumbs/") })); } throw; } if (Request.IsAjaxRequest()) { return(Json(new { id = newblog.BlogID, src = BlogHelper.firstImgPath(newblog, true) })); } return(RedirectToAction("Details", new { id = newblog.BlogID })); }