public static MetatagListModel GetMetatagListModel() { var metatags = new List <Metatag>(); var m = new MetatagListModel("All", metatags); using (var db = new FusekiContext()) { var allTags = db.Tags.Select(el => el.Name).ToHashSet(); foreach (var tag in allTags) { var mt = new Metatag(); mt.Name = tag; var articleIds = db.Tags.Where(el => el.Name == tag).Select(el => el.ArticleId); var articles = db.Articles.Where(el => articleIds.Contains(el.Id) && el.Published).ToList();; if (articles.Count == 0) { continue; } mt.Articles = articles; mt.Count = articles.Count; mt.Created = articles.OrderBy(el => el.Created).FirstOrDefault()?.Created ?? DateTime.MinValue; mt.Updated = articles.OrderByDescending(el => el.Updated).FirstOrDefault()?.Updated ?? DateTime.MinValue; metatags.Add(mt); } } m.Metatags = metatags.OrderByDescending(el => el.Count).ThenBy(el => el.Name).ToList(); return(m); }
public IActionResult Search(string term) { var model = new SearchResultModel(Renderer); term = term.ToLower(); model.Term = term; using (var db = new FusekiContext()) { var art = db.Articles .Include(el => el.Tags) .Where(el => el.Title.ToLower().Contains(term)) .OrderBy(el => el.Title); model.TitleMatches = art.ToList(); var body = db.Articles .Include(el => el.Tags) .Where(el => el.Body.ToLower().Contains(term)) .OrderBy(el => el.Title); model.BodyMatches = body.ToList(); //var tags = db.Tags.Where(el => el.Name.ToLower().Contains(term)); //model.TagMatches = tags.ToList(); } ViewData["Title"] = $"Search for: {term}"; return(View("SearchResult", model)); }
/// <summary> /// This is for tag viewing generically /// </summary> private string MakeTagTable(Tag tag, bool inAdmin) { var sb = new StringBuilder(); var header = "<table><thead><tr><th>Article<th>Body<th>Tags<th>Updated</thead><tbody>"; sb.Append(header); using (var db = new FusekiContext()) { var articleIds = db.Tags.Where(t => t.Name == tag.Name).Select(el => el.ArticleId); var articles = db.Articles .Include(ee => ee.Tags) .Where(ee => ee.Published) .Where(el => articleIds.Contains(el.Id)) .OrderBy(el => el.Title); foreach (var article in articles) { var row = MakeArticleRowForList(article, false, inAdmin); sb.Append(row); } } var end = "</tbody></table>"; sb.Append(end); return(sb.ToString()); }
public IActionResult PublishArticle(int id) { Logger.LogMessage($"PublishToggle: {id}"); using (var db = new FusekiContext()) { var article = db.Articles.First(el => el.Id == id); if (article == null) { return(new JsonResult(new { Message = "No article" })); } if (article.Published) { article.Published = false; db.SaveChanges(); } else { if (article.Deleted) { return(new JsonResult(new { Message = "Deleted alread" })); } article.Published = true; db.SaveChanges(); } return(new JsonResult(new { Message = "Success", Status = article.Published })); } }
/// <summary> /// published articles with id<=294 will be have redirects for their titles. /// This doesn't cover the case an article title gets changed - those inbound links are just lost. /// </summary> private void RecreateHtaccess(PublishConfiguration pc) { var baseHtaccess = "RewriteEngine On\n" + "Redirect permanent \"/home/comparison.html\" \"/home/ComparisonoflifeinPiscatawayNewJerseyKochiJapanandZhuzhouChina.html\""; var oldIds = new List <int>() { 1, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 92, 93, 94, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 127, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 165, 178, 179, 222, 223, 224, 226, 227, 229, 234, 235, 236, 237, 244, 246, 247, 249, 250, 260, 263, 265, 267, 268, 270, 272, 273, 275, 277, 279, 282, 288, 291, 292, 293 }; var lines = new List <string>(); using (var db = new FusekiContext()) { foreach (var article in db.Articles.Where(el => oldIds.Contains(el.Id) && el.Title != null && el.Title.Length > 0)) { var oldFilename = article.MakeOldFilename(false); var newFilename = article.MakeFilename(false); if (oldFilename != newFilename) //doh { var str = $"Redirect permanent \"/home/{oldFilename}\" \"/home/{newFilename}\""; lines.Add(str); } } } baseHtaccess += "\n" + string.Join("\n", lines); var htaccessPath = pc.TempBase + "/.htaccess"; System.IO.File.WriteAllText(htaccessPath, baseHtaccess); }
public Article FindArticleForInternalLink(string text) { using (var db = new FusekiContext()) { var candidates = db.Articles.Where(el => el.Title.ToLower().StartsWith(text.ToLower())); var best = candidates.OrderByDescending(el => el.Title.Length).FirstOrDefault(); return(best); } }
public IActionResult UpdateArticle(ArticleModel model) { if (ModelState.IsValid) { using (var db = new FusekiContext()) { var article = db.Articles .Include(aa => aa.Tags) .First(el => el.Id == model.Id); //allow extended chars in title. But links and finding will strip them. article.Title = model.Title; var normalized = Renderer.Normalize(model.Body); article.Body = normalized; var now = DateTime.Now; article.Updated = now; if (article.Created == DateTime.MinValue) { article.Created = now; } //rectify tags. var empty = new List <string>(); var tags = model.Tags?.Split(",").Select(el => el.Trim()) ?? new string[0]; var newTagNames = tags .Select(el => el.Trim()) .Where(ee => !string.IsNullOrWhiteSpace(ee)) .ToHashSet(); var existingTags = article.Tags.Select(el => el.Name).ToHashSet(); var todelete = existingTags.Except(newTagNames); var toadd = newTagNames.Except(existingTags); foreach (var bad in todelete) { var tag = db.Tags.Where(el => el.ArticleId == article.Id && el.Name == bad).First(); db.Remove(tag); } foreach (var good in toadd) { var tag = CreateTag(article, good); db.Add(tag); } db.SaveChanges(); return(Redirect($"../{model.Title}")); } } else { return(View()); } }
public IActionResult RandomUnpublished() { using (var db = new FusekiContext()) { var arti = db.Articles.Where(el => el.Published == false && el.Deleted == false); var n = new System.Random().Next(arti.Count()); var article = arti.Skip(n).First(); return(RedirectToAction("ViewArticle", "Admin", new { title = article.Title })); } }
public IActionResult Index() { using (var db = new FusekiContext()) { var pubs = db.Publications.OrderByDescending(el => el.Id).ToList(); var model = new PublicationListModel(pubs); ViewData["Title"] = $"Publications"; return(View("PublicationList", model)); } }
/// <summary> /// Weigh them by inverse popularity of related tag, not by count strictly. /// </summary> public List <RelatedArticle> GetRelatedArticles(Article article) { var tagnames = article.Tags.Select(el => el.Name); var counts = new Dictionary <string, int>(); using (var db = new FusekiContext()) { foreach (var tag in tagnames) { var count = db.Tags.Where(el => el.Name == tag).Count(); counts[tag] = count; } //calculate the related tags, and then the score of every other article in the system. var scoredArticles = new Dictionary <Article, double>(); foreach (var otherArticle in db.Articles .Include(el => el.Tags) .Where(el => el.Published)) { if (otherArticle.Id == article.Id) { continue; } var uniqs = otherArticle.Tags.Select(el => el.Name).ToHashSet(); uniqs.IntersectWith(tagnames); var score = uniqs.Select(el => 1.0 / counts[el]).Sum(); scoredArticles[otherArticle] = score; } var orderedRelated = scoredArticles.ToList().OrderByDescending(el => el.Value); var res = new List <RelatedArticle>(); foreach (var el in orderedRelated) { if (el.Value == 0) { break; } if (res.Count > 10) { break; } var relatedArticle = db.Articles .Include(el => el.Tags) .FirstOrDefault(ra => ra.Id == el.Key.Id); //doh, calculating these again. //var relatedTags = relatedArticle.Tags.Where(el => tagnames.Contains(el.Name)).ToList(); res.Add(new RelatedArticle(relatedArticle, relatedArticle.Tags)); } return(res); } }
public IActionResult SetTags(int id, string tagLine = "") { if (string.IsNullOrEmpty(tagLine)) { tagLine = ""; } var newTags = Helpers.TagLine2Tags(tagLine); var didSomething = false; var result = ""; using (var db = new FusekiContext()) { var image = db.Images .Include(el => el.ImageTags) .FirstOrDefault(el => el.Id == id); var exiTags = image.ImageTags ?? new List <ImageTag>(); //exiTags = new List<ImageTag>(); var toDelete = new List <ImageTag>(); foreach (var tag in newTags) { if (exiTags.FirstOrDefault(el => el.Name == tag) == null) { var newImageTag = new ImageTag(); newImageTag.Image = image; newImageTag.Name = tag; db.Add(newImageTag); didSomething = true; result += $"\ncreated new tag for image: {tag}"; } } foreach (var exiTag in exiTags) { if (newTags.FirstOrDefault(el => el == exiTag.Name) == null) { db.Remove(exiTag); didSomething = true; result += $"\nremoved old tag on image: {exiTag.Name}"; } } if (didSomething) { db.SaveChanges(); } } var arm = new ActionResultModel(); arm.NextLink = "/image/viewall"; arm.NextLinkDescription = "back to image list"; arm.SetResult(result); return(View("ActionResult", arm)); }
public IActionResult ListAll() { using (var db = new FusekiContext()) { var articles = db.Articles .Where(el => el.Title != null && el.Title.Length > 0) .Include(ee => ee.Tags) .ToList(); var m = new ListModel("All", articles); ViewData["Title"] = $"All articles"; return(View("List", m)); } }
public IActionResult CreateArticle() { using (var db = new FusekiContext()) { var article = new Article(); var rnd = new System.Random(); article.Title = $"draft{rnd.Next(1000)}"; article.Body = ""; var a = db.Add(article); db.SaveChanges(); return(Redirect($"article/edit/{a.Entity.Title}")); } }
private bool PublishArticlesAndTags(PublishConfiguration pc, out int count) { count = 0; using (var db = new FusekiContext()) { var articleIds = new List <int>(); try { foreach (var article in db.Articles .Include(el => el.Tags) .Where(el => el.Published == true)) { var filename = article.MakeFilename(false); Console.WriteLine($"Writing: {filename}"); var path = MakePath(pc, filename); //todo add in better title generation code here. var combined = Renderer.GenerateArticleString(Settings, article, false); System.IO.File.WriteAllText(path, combined); articleIds.Add(article.Id); Logger.LogMessage($"Published: {article.Title}"); count++; } } catch (Exception ex) { Console.WriteLine(ex); } //todo only publish tags where the article is published. var tags = db.Tags.Where(t => articleIds.Contains(t.ArticleId)).ToHashSet(); var tagDir = pc.TempBase + "/tags"; if (!System.IO.Directory.Exists(tagDir)) { System.IO.Directory.CreateDirectory(tagDir); } foreach (var tag in tags) { PublishTag(pc, tag, false); } RecreateHtaccess(pc); } return(true); }
public IActionResult Delete(int id) { using (var db = new FusekiContext()) { var image = db.Images .Include(el => el.ImageTags) .FirstOrDefault(el => el.Id == id); if (image != null) { image.Deleted = true; } db.SaveChanges(); } return(RedirectToAction("ViewImages")); }
/// <summary> /// This works reasonably well, but doesn't penalize connections for having lots of tags NOT in common. /// It's also annoying that 2 is a constant, and that having increased similarity in tags doesn't help much. i.e. 1=>2 goes in value from 1 to 1/2 to 1/3, not much when 1's are floating around /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static double GetTagCommonality(Article a, Article b) { using (var db = new FusekiContext()) { var atags = a.Tags.Select(el => el.Name); var btags = b.Tags.Select(el => el.Name); var c = atags.Intersect(btags); var incommon = c.Count(); if (incommon == 0) { return(2); } return(1 / incommon); } }
private static string MakeTagLink(Tag tag, bool highlightTag, bool inTagDir, bool inAdmin) { var taglink = $"{tag.MakeFilename(inAdmin)}"; var tagFolder = inTagDir ? "" : "tags/"; var klass = highlightTag ? "highlight " : ""; var tagCount = 0; using (var db = new FusekiContext()) { //tagCount = db.Tags.Where(el => el.Name == tag.Name && el.Article.Published == true).Count(); } var line = $"<div class=\"{klass}tag\"><a class=taglink href=\"{tagFolder}{taglink}\">{tag.Name}</a></div>"; return(line); }
public IActionResult Partition(int partitionCount) { //var partitioner = new Partitioner<Article>((a, b) => Comparators.GetLengthDistance(a, b), (a, b) => Comparators.ArticleKeyLookup(a, b)); var partitioner = new Partitioner <Article>((a, b) => Comparators.GetTagCommonality(a, b), (a, b) => Comparators.ArticleKeyLookup(a, b)); using (var db = new FusekiContext()) { var articles = db.Articles.Where(el => el.Published == true) .Include(el => el.Tags).ToList(); var r = new Random(); articles = articles.OrderBy(el => r.NextDouble()).ToList(); var partitiondata = partitioner.GetPartitions(partitionCount, articles); var model = new ArticlePartitionModel(partitiondata); return(View("ArticlePartitions", model)); } }
/// <summary> /// TODO: what's the difference? /// </summary> public List <RelatedArticle> GetRelatedArticlesNaive(Article article) { var tagnames = article.Tags.Select(el => el.Name); using (var db = new FusekiContext()) { var relatedTags = db.Tags.Include(el => el.Article).Where(el => tagnames.Contains(el.Name)); var scores = new Dictionary <int, List <Tag> >(); foreach (var tag in relatedTags) { if (tag.ArticleId == article.Id) { continue; } if (!tag.Article.Published) { continue; } if (!scores.ContainsKey(tag.ArticleId)) { scores[tag.ArticleId] = new List <Tag>(); } scores[tag.ArticleId].Add(tag); } var orderedRelated = scores.ToList().OrderByDescending(el => el.Value.Count); var res = new List <RelatedArticle>(); foreach (var el in orderedRelated) { if (el.Value.Count == 0) { break; } if (res.Count > 10) { break; } //var relatedArticle = db.Articles.Find(el.Key); var relatedArticle = db.Articles.FirstOrDefault(ra => ra.Id == el.Key); res.Add(new RelatedArticle(relatedArticle, el.Value)); } return(res); } }
public IActionResult EditArticle(string title) { using (var db = new FusekiContext()) { var article = db.Articles .Include(el => el.Tags) .First(el => el.Title.StartsWith(title)); //startswith to allow titles with ? marks in them. Doh. var normalized = Renderer.Normalize(article.Body); article.Body = normalized; var liveUrl = string.Format(Settings.LiveUrlTemplate, article.MakeFilename(false), true); var editUrl = string.Format(Settings.EditUrlTemplate, article.Title, false); var model = new ArticleModel(article, liveUrl, editUrl, Renderer.ToHtml(normalized)); ViewData["Title"] = $"Editing {article.Title}"; return(View("EditArticle", model)); } }
public IActionResult ViewImageTag(string term) { using (var db = new FusekiContext()) { var model = new ViewImagesModel(); model.Term = term; term = term.ToLower(); var images = new List <Image>(); string matchType = ""; var tag = db.ImageTags.FirstOrDefault(el => el.Name.ToLower() == term); if (tag == null) { tag = db.ImageTags.FirstOrDefault(el => el.Name.ToLower().StartsWith(term)); matchType = "prefix"; } else if (tag == null) { tag = db.ImageTags.FirstOrDefault(el => el.Name.ToLower().Contains(term)); matchType = "substring"; } else if (tag == null) { tag = null; matchType = "none"; } else { matchType = "exact"; } if (tag != null) { var tagName = tag.Name; var tags = db.ImageTags.Where(el => el.Name == tagName); images = tags.Select(el => el.Image) .Include(el => el.ImageTags) .ToList(); } model.Images = images; model.MatchType = matchType; return(View("ViewImages", model)); } }
public IActionResult Publish() { var model = new PublicationResultModel(); var publishResult = Publisher.Publish(); var publication = new Publication(); publication.ArticleCount = publishResult.Count; publication.PublicationTime = DateTime.Now; using (var db = new FusekiContext()) { db.Add(publication); db.SaveChanges(); } model.Publication = publication; ViewData["Title"] = $"PublicationResult"; return(View("PublicationResult", model)); }
public IActionResult RestoreImages() { var images = System.IO.Directory.GetFiles(PublishConfiguration.ImageSource).Select(el => el.Replace(PublishConfiguration.ImageSource, "").Replace("\\", "")); using (var db = new FusekiContext()) { foreach (var imagefn in images) { var exi = db.Images.FirstOrDefault(el => el.Filename == imagefn); if (exi == null) { var image = new Image(); image.Filename = imagefn; db.Add(image); } } db.SaveChanges(); } return(null); }
public IActionResult Search(string term) { Logger.LogMessage($"Searched for: {term}"); var model = new SearchResultModel(Renderer); term = term.ToLower(); model.Term = term; using (var db = new FusekiContext()) { var art = db.Articles.Where(el => el.Title.ToLower().Contains(term)); model.TitleMatches = art.ToList(); var body = db.Articles.Where(el => el.Body.ToLower().Contains(term)); model.BodyMatches = body.ToList(); //var tags = db.Tags.Where(el => el.Name.ToLower().Contains(term)); //model.TagMatches = tags.ToList(); } return(new JsonResult(model)); }
public IActionResult Tag(string name) { using (var db = new FusekiContext()) { var tag = db.Tags .Where(el => el.Name == name).FirstOrDefault(); if (tag == null) { return(Redirect("../../")); } var articleIds = db.Tags.Where(el => el.Name == name).Select(el => el.ArticleId); var articles = db.Articles .Where(el => articleIds.Contains(el.Id)) .Where(el => el.Published) .Include(el => el.Tags) .OrderBy(el => el.Title) .ToList(); var model = new ListModel($"Tag: {tag.Name}", articles, name); ViewData["Title"] = $"Search: {name}"; return(View("List", model)); } }
public IActionResult ViewImages(string term) { using (var db = new FusekiContext()) { var model = new ViewImagesModel(); model.Term = term; IOrderedQueryable <Image> images; if (!string.IsNullOrEmpty(term)) { images = db.Images.Where(el => el.Filename.ToLower().Contains(term.ToLower())).OrderByDescending(el => el.Id); model.Term = "Search for: " + term; } else { images = db.Images.OrderByDescending(el => el.Id).Take(20).OrderByDescending(el => el.Id); } model.Images = images .Where(el => el.Deleted == false) .Include(el => el.ImageTags) .ToList(); return(View("ViewImages", model)); } }
public IActionResult ViewArticle(string title) { using (var db = new FusekiContext()) { var article = db.Articles .Include(ee => ee.Tags) .FirstOrDefault(el => el.Title.StartsWith(title)); //startswith to fix question mark thing. if (article == null) { return(RedirectToAction("List"));; } var related = ArticleData.GetRelatedArticles(article); var liveUrl = string.Format(Settings.LiveUrlTemplate, article.MakeFilename(true)); var editUrl = string.Format(Settings.EditUrlTemplate, article.Title, false); var articleString = Renderer.GenerateArticleString(Settings, article, true); var model = new ArticleModel(article, liveUrl, editUrl, articleString, related); ViewData["Title"] = $"{article.Title}"; return(View("Article", model)); } }
public IActionResult Partition2(int partitionCount) { using (var db = new FusekiContext()) { var articles = db.Articles.Where(el => el.Published == true) .Include(el => el.Tags).Take(20).ToList(); //get a tag vector for each article. var allTags = new HashSet <string>(); //TODO: What happens if we remove all tags which only occur once. foreach (var article in articles) { foreach (var tag in article.Tags) { allTags.Add(tag.Name); } } var newAllTags = new HashSet <string>(); foreach (var t in allTags) { var relatedArticles = db.Articles.Where(el => el.Tags.Select(tag => tag.Name).Contains(t)); if (relatedArticles.Count() > 1) { newAllTags.Add(t); } } allTags = newAllTags; var allTagsOrdered = allTags.OrderBy(el => el); var obs = new List <List <double> >(); var dict = new Dictionary <string, object>(); foreach (var article in articles) { var articleTags = article.Tags.Select(el => el.Name); var vector = new List <double>(); foreach (var tag in allTagsOrdered) { if (articleTags.Contains(tag)) { vector.Add(1); } else { vector.Add(0); } } obs.Add(vector); } var vecvec = obs.Select(el => el.ToArray()).ToArray(); var kmeans = new KMeans(k: partitionCount); var clusters = kmeans.Learn(vecvec); dict["Kmeans Error"] = kmeans.Error; dict["dimensionality"] = kmeans.Dimension; dict["Iterations"] = kmeans.Iterations; dict["MaxIterations"] = kmeans.MaxIterations; dict["Tolerance"] = kmeans.Tolerance; int[] labels = clusters.Decide(vecvec); //labels is array[articleId] => partitionNumber var ii = 0; var psets = new List <PartitionSet <Article> >(); //this is totally fake. TODO: refactor these to be dumber - no need to have comparators etc. var dm = new DistanceMetrics <Article>((a, b) => Comparators.GetTagCommonality(a, b), (a, b) => Comparators.ArticleKeyLookup(a, b)); while (ii < partitionCount) { //TODO: is accord zero indexed? psets.Add(new PartitionSet <Article>(dm, ii)); ii++; } var index = 0; foreach (var l in labels) { var article = articles[index]; index++; psets[l].Add(article); } var partitiondata = new PartitionData <Article>(psets, dict); var model = new ArticlePartitionModel(partitiondata); return(View("ArticlePartitions", model)); } }
///obviously impossible to test every possibility. ///Might be possible to iterate or do local hill climbing? order matters for all that. ///title length has weird transitivity; don't use that because it won't apply for other metrics. ///I could just do it 100 times with random starts, iterating adding members to the set which they are closest to. ///Then as a final step test each element to see if it belongs better in another set. public PartitionData <T> GetPartitions(int partitionCount, List <T> Elements) { if (partitionCount < 2 || partitionCount > 100) { throw new Exception("Are you sure you want to generate that many partitions?"); } var sets = new List <PartitionSet <T> >(); var ii = 0; while (ii < partitionCount) { var px = new PartitionSet <T>(metrics, ii); sets.Add(px); ii++; } using (var db = new FusekiContext()) { foreach (var el in Elements) { var targetSet = FindBestPartition(el, sets); targetSet.Add(el); } } //initial assignment done. //now iterate over each item, removing it and then readding it where it belongs til we reach stability or N iterations. var loopCt = 0; var moveCt = 100; var stats = new Dictionary <string, object>(); stats["InitialQuality"] = FindQuality(sets); while (loopCt < 200) { moveCt = 0; var PlannedMoves = new Dictionary <T, Tuple <PartitionSet <T>, PartitionSet <T> > >(); foreach (var set in sets) { foreach (var el in set.Items) { //remove it first so it has a free choice var targetSet = FindBestPartition(el, sets); if (targetSet != set) { moveCt++; var data = new Tuple <PartitionSet <T>, PartitionSet <T> >(set, targetSet); PlannedMoves[el] = data; } if (moveCt > 0) { break; } } if (moveCt > 0) { break; } } //problem: I am moving to favor the article, not to favor the overall quality of matches. i.e. if there is a linking article who is happier in a dedicated node, but removing him hurts the parent, how to do it? foreach (var article in PlannedMoves.Keys) { var tup = PlannedMoves[article]; var old = tup.Item1; var newset = tup.Item2; old.Remove(article); newset.Add(article); } loopCt++; stats[$"quality:{loopCt} moved:{moveCt}"] = FindQuality(sets); if (moveCt == 0) { break; } } stats["moveCt"] = moveCt; stats["loopCt"] = loopCt; stats["Final quality"] = FindQuality(sets); var pdata = new PartitionData <T>(sets, stats); return(pdata); }
public IActionResult UploadPost(UploadFileModel file, string tagLine) { //possibly accept the override filename var filename = file.Image.FileName; if (string.IsNullOrEmpty(file.Filename)) { file.Filename = file.Filename.ToLower(); } else { filename = file.Filename; } filename = CleanFilename(filename); if (!ValidateImageExtension(filename)) { var extFromImage = Path.GetExtension(file.Image.FileName); if (ValidateImageExtension(extFromImage)) { filename = filename + extFromImage; } else { throw new Exception("Invalid extension on filename" + filename); } } var targetPath = $"{PublishConfiguration.ImageSource}/{filename}"; if (System.IO.File.Exists(targetPath)) { throw new System.Exception("Already exists."); } using (var stream = System.IO.File.Create(targetPath)) { file.Image.CopyTo(stream); } using (var db = new FusekiContext()) { var image = new Image(); image.Filename = filename; db.Add(image); var tags = Helpers.TagLine2Tags(tagLine); foreach (var tag in tags) { var t = new ImageTag(); t.Image = image; t.Name = tag; db.Add(t); } db.SaveChanges(); } var arm = new ActionResultModel(); arm.NextLink = "/image/upload"; arm.NextLinkDescription = "Return to image upload"; arm.SetResult("Uploaded image"); return(View("ActionResult", arm)); }