├── .gitattributes ├── .gitignore ├── MiniBlogFormatter.sln ├── MiniBlogFormatter ├── App.config ├── Formatters │ ├── BlogEngineFormatter.cs │ ├── BlogMLFormatter.cs │ ├── DasBlogFormatter.cs │ ├── FormatterHelpers.cs │ ├── GhostFormatter.cs │ └── WordpressFormatter.cs ├── MiniBlogFormatter.csproj ├── Models │ ├── Comment.cs │ ├── GhostData.cs │ ├── Post.cs │ └── Storage.cs ├── Program.cs └── packages.config ├── README.md └── packages └── Newtonsoft.Json.6.0.6 ├── Newtonsoft.Json.6.0.6.nupkg ├── lib ├── net20 │ ├── Newtonsoft.Json.dll │ └── Newtonsoft.Json.xml ├── net35 │ ├── Newtonsoft.Json.dll │ └── Newtonsoft.Json.xml ├── net40 │ ├── Newtonsoft.Json.dll │ └── Newtonsoft.Json.xml ├── net45 │ ├── Newtonsoft.Json.dll │ └── Newtonsoft.Json.xml ├── netcore45 │ ├── Newtonsoft.Json.dll │ └── Newtonsoft.Json.xml ├── portable-net40+sl5+wp80+win8+wpa81 │ ├── Newtonsoft.Json.dll │ └── Newtonsoft.Json.xml └── portable-net45+wp80+win8+wpa81+aspnetcore50 │ ├── Newtonsoft.Json.dll │ └── Newtonsoft.Json.xml └── tools └── install.ps1 /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /MiniBlogFormatter.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.20919.2 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniBlogFormatter", "MiniBlogFormatter\MiniBlogFormatter.csproj", "{B92EB6D7-8C50-481C-B68D-A7C04CAFF65C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {B92EB6D7-8C50-481C-B68D-A7C04CAFF65C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {B92EB6D7-8C50-481C-B68D-A7C04CAFF65C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {B92EB6D7-8C50-481C-B68D-A7C04CAFF65C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {B92EB6D7-8C50-481C-B68D-A7C04CAFF65C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /MiniBlogFormatter/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Formatters/BlogEngineFormatter.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Text.RegularExpressions; 3 | using System.Xml; 4 | 5 | namespace MiniBlogFormatter 6 | { 7 | public class BlogEngineFormatter 8 | { 9 | private Regex rxFiles = new Regex("(href|src)=\"(([^\"]+)?(file|image)\\.axd\\?(file|picture)=([^\"]+))\"", RegexOptions.IgnoreCase); 10 | private Regex rxAggBug = new Regex("", RegexOptions.IgnoreCase); 11 | 12 | public void Format(string fileName, string targetFolderPath, string categoriesFileName) 13 | { 14 | XmlDocument doc = new XmlDocument(); 15 | doc.Load(fileName); 16 | 17 | XmlNode isDeletedNode = doc.SelectSingleNode("post/isdeleted"); 18 | 19 | bool isDeleted = isDeletedNode != null ? isDeletedNode.InnerText == "True" : false; 20 | 21 | if (!isDeleted) 22 | { 23 | FormatSlug(doc); 24 | FormatFileReferences(doc); 25 | RemoveAggBug(doc); 26 | RemoveSpamComments(doc); 27 | 28 | XmlDocument categories = new XmlDocument(); 29 | categories.Load(categoriesFileName); 30 | FormatCategories(doc, categories); 31 | 32 | string newFileName = Path.Combine(targetFolderPath, Path.GetFileName(fileName)); 33 | doc.Save(newFileName); 34 | } 35 | } 36 | 37 | private void FormatFileReferences(XmlDocument doc) 38 | { 39 | XmlNode content = doc.SelectSingleNode("post/content"); 40 | 41 | if (content != null) 42 | { 43 | foreach (Match match in rxFiles.Matches(content.InnerText)) 44 | { 45 | content.InnerText = content.InnerText.Replace(match.Groups[2].Value, "/posts/files/" + match.Groups[6].Value); 46 | } 47 | } 48 | } 49 | 50 | private void FormatSlug(XmlDocument doc) 51 | { 52 | XmlNode slug = doc.SelectSingleNode("//slug"); 53 | 54 | if (slug != null) 55 | { 56 | slug.InnerText = FormatterHelpers.FormatSlug(slug.InnerText); 57 | } 58 | } 59 | 60 | private void RemoveAggBug(XmlDocument doc) 61 | { 62 | XmlNode content = doc.SelectSingleNode("post/content"); 63 | 64 | if (content != null) 65 | { 66 | content.InnerText = rxAggBug.Replace(content.InnerText, string.Empty); 67 | } 68 | } 69 | 70 | private void RemoveSpamComments(XmlDocument doc) 71 | { 72 | XmlNodeList comments = doc.SelectNodes("//comment"); 73 | 74 | for (int i = comments.Count - 1; i > -1; i--) 75 | { 76 | XmlNode comment = comments[i]; 77 | bool approved = comment.Attributes["approved"] != null ? comment.Attributes["approved"].InnerText == "True" : true; 78 | bool deleted = comment.Attributes["deleted"] != null ? comment.Attributes["deleted"].InnerText == "True" : true; 79 | 80 | if (!approved || deleted) 81 | { 82 | comment.ParentNode.RemoveChild(comment); 83 | } 84 | } 85 | } 86 | 87 | private void FormatCategories(XmlDocument doc, XmlDocument categoriesDoc) 88 | { 89 | XmlNodeList categories = doc.SelectNodes("//category"); 90 | 91 | foreach (XmlNode category in categories) 92 | { 93 | string id = category.InnerText; 94 | XmlNode name = categoriesDoc.SelectSingleNode("//category[@id='" + id + "']"); 95 | 96 | if (name != null) 97 | { 98 | category.InnerText = name.InnerText; 99 | } 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Formatters/BlogMLFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Xml.Linq; 8 | 9 | namespace MiniBlogFormatter 10 | { 11 | public class BlogMLFormatter 12 | { 13 | XNamespace ns = "http://www.blogml.com/2006/09/BlogML"; 14 | 15 | public void Format(string fileName, string targetFolderPath) 16 | { 17 | XDocument doc = XDocument.Load(fileName); 18 | 19 | Dictionary authors = doc.Root.Element(ns + "authors").Elements(ns + "author").ToDictionary(x => x.Attribute("id").Value, x => x.Element(ns + "title").Value); 20 | Dictionary categories = doc.Root.Element(ns + "categories").Elements(ns + "category").ToDictionary(x => x.Attribute("id").Value, x => x.Element(ns + "title").Value); 21 | 22 | foreach (XElement postData in doc.Root.Element(ns + "posts").Elements(ns + "post")) 23 | { 24 | Post post = ParsePost(postData, authors, categories); 25 | 26 | Storage.Save(post, Path.Combine(targetFolderPath, post.ID + ".xml")); 27 | } 28 | } 29 | 30 | public void ConvertFromBase64(string fileName, string targetFileName) 31 | { 32 | XDocument doc = XDocument.Load(fileName); 33 | var query = doc.Descendants(ns + "content") 34 | .Where(node => (string)node.Attribute("type") == "base64"); 35 | foreach (var item in query) 36 | { 37 | var content = Encoding.UTF8.GetString(Convert.FromBase64String(item.Value)); 38 | 39 | item.SetValue(content); 40 | } 41 | 42 | doc.Save(targetFileName); 43 | } 44 | 45 | Post ParsePost(XElement postData, Dictionary authors, Dictionary categories) 46 | { 47 | Post post = new Post() 48 | { 49 | Title = postData.Element(ns + "title").Value, 50 | Content = postData.Element(ns + "content").Value, 51 | PubDate = (DateTime)postData.Attribute("date-created"), 52 | LastModified = (DateTime)postData.Attribute("date-modified"), 53 | IsPublished = (bool)postData.Attribute("approved"), 54 | Categories = postData.Descendants(ns + "category").Select(x => categories[x.Attribute("ref").Value]).ToArray() 55 | }; 56 | 57 | XElement name = postData.Element(ns + "post-name"); 58 | 59 | if (name != null) 60 | post.Slug = name.Value; 61 | else 62 | post.Slug = FormatterHelpers.FormatSlug(post.Title); 63 | 64 | XElement author = postData.Descendants(ns + "author").FirstOrDefault(); 65 | 66 | if (author != null) 67 | { 68 | var thisArthor = author.Attribute("ref").Value; 69 | foreach(var thisKey in authors.Keys) 70 | { 71 | // Fixes issue when author name has different cases from the Key value of Authors 72 | if(thisArthor.Equals(thisKey, StringComparison.CurrentCultureIgnoreCase)) 73 | { 74 | post.Author = authors[thisKey]; 75 | } 76 | } 77 | } 78 | 79 | foreach (XElement commentData in postData.Descendants(ns + "comment")) 80 | { 81 | if (commentData.Attribute("approved").Value == "true") 82 | { 83 | post.Comments.Add(new Comment() 84 | { 85 | ID = commentData.Attribute("id").Value, 86 | PubDate = (DateTime)commentData.Attribute("date-created"), 87 | Content = commentData.Element(ns + "content").Value, 88 | Author = (string)commentData.Attribute("user-name"), 89 | Website = (string)commentData.Attribute("user-url"), 90 | Email = (string)commentData.Attribute("user-email"), 91 | }); 92 | } 93 | } 94 | 95 | return post; 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Formatters/DasBlogFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text.RegularExpressions; 5 | using System.Xml; 6 | using System.Linq; 7 | 8 | namespace MiniBlogFormatter 9 | { 10 | public class DasBlogFormatter 11 | { 12 | private Regex rxFiles = new Regex("(href|src)=\"(([^\"]+)(/content/binary/)([^\"]+))\"", RegexOptions.IgnoreCase); 13 | 14 | public void Format(string originalFolderPath, string targetFolderPath) 15 | { 16 | FormatPosts(originalFolderPath, targetFolderPath); 17 | FormatComments(originalFolderPath, targetFolderPath); 18 | } 19 | 20 | private void FormatPosts(string originalFolderPath, string targetFolderPath) 21 | { 22 | foreach (string file in Directory.GetFiles(originalFolderPath, "*.xml")) 23 | { 24 | if (!file.EndsWith("dayentry.xml", StringComparison.OrdinalIgnoreCase)) 25 | continue; 26 | 27 | XmlDocument docOrig = LoadDocument(file); 28 | XmlNamespaceManager nsm = LoadNamespaceManager(docOrig); 29 | 30 | foreach (XmlNode entry in docOrig.SelectNodes("//Entry", nsm)) 31 | { 32 | Post post = new Post(); 33 | post.Categories = FormatCategories(entry.SelectSingleNode("Categories")).ToArray(); 34 | post.Title = entry.SelectSingleNode("Title").InnerText; 35 | post.Slug = FormatterHelpers.FormatSlug(post.Title); 36 | post.PubDate = DateTime.Parse(entry.SelectSingleNode("//Created").InnerText); 37 | post.LastModified = DateTime.Parse(entry.SelectSingleNode("//Modified").InnerText); 38 | post.Content = FormatFileReferences(entry.SelectSingleNode("Content").InnerText); 39 | post.Author = entry.SelectSingleNode("Author").InnerText; 40 | post.IsPublished = bool.Parse(ReadValue(entry.SelectSingleNode("IsPublic"), "true")); 41 | 42 | string newFile = Path.Combine(targetFolderPath, entry.SelectSingleNode("EntryId").InnerText + ".xml"); 43 | Storage.Save(post, newFile); 44 | } 45 | } 46 | } 47 | 48 | private string FormatFileReferences(string content) 49 | { 50 | foreach (Match match in rxFiles.Matches(content)) 51 | { 52 | content = content.Replace(match.Groups[2].Value, "/posts/files/" + match.Groups[5].Value); 53 | } 54 | 55 | return content; 56 | } 57 | 58 | private static XmlNamespaceManager LoadNamespaceManager(XmlDocument docOrig) 59 | { 60 | XmlNamespaceManager nsm = new XmlNamespaceManager(docOrig.NameTable); 61 | nsm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 62 | nsm.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); 63 | return nsm; 64 | } 65 | 66 | private void FormatComments(string originalFolderPath, string targetFolderPath) 67 | { 68 | foreach (string file in Directory.GetFiles(originalFolderPath, "*.xml")) 69 | { 70 | if (!file.EndsWith("dayfeedback.xml", StringComparison.OrdinalIgnoreCase)) 71 | continue; 72 | 73 | XmlDocument docOrig = LoadDocument(file); 74 | XmlNamespaceManager nsm = LoadNamespaceManager(docOrig); 75 | 76 | foreach (XmlNode entry in docOrig.SelectNodes("//Comment", nsm)) 77 | { 78 | XmlNode idNode = entry.SelectSingleNode("TargetEntryId"); 79 | string postFile = Path.Combine(targetFolderPath, idNode.InnerText + ".xml"); 80 | 81 | if (!File.Exists(postFile)) 82 | continue; 83 | 84 | bool isSpam = ReadValue(entry.SelectSingleNode("SpamState"), "n/a") == "Spam"; 85 | if (isSpam) 86 | continue; 87 | 88 | Post post = Storage.LoadPost(postFile); 89 | 90 | Comment comment = new Comment(); 91 | comment.Author = ReadValue(entry.SelectSingleNode("Author"), "n/a"); 92 | comment.Email = ReadValue(entry.SelectSingleNode("AuthorEmail"), ""); 93 | comment.Ip = entry.SelectSingleNode("AuthorIPAddress").InnerText; 94 | comment.Website = entry.SelectSingleNode("AuthorHomepage").InnerText; 95 | comment.Content = entry.SelectSingleNode("Content").InnerText; 96 | comment.PubDate = DateTime.Parse(ReadValue(entry.SelectSingleNode("Created"), "")); 97 | comment.ID = entry.SelectSingleNode("EntryId").InnerText; 98 | comment.UserAgent = ReadValue(entry.SelectSingleNode("AuthorUserAgent"), ""); 99 | 100 | bool isOpenId = bool.Parse(ReadValue(entry.SelectSingleNode("OpenId"), "false")); 101 | 102 | if (isOpenId) 103 | { 104 | comment.Author = "n/a"; 105 | } 106 | 107 | post.Comments.Add(comment); 108 | 109 | Storage.Save(post, postFile); 110 | } 111 | } 112 | } 113 | 114 | private static XmlDocument LoadDocument(string file) 115 | { 116 | string doc = File.ReadAllText(file).Replace(" xmlns=\"urn:newtelligence-com:dasblog:runtime:data\"", string.Empty); 117 | 118 | XmlDocument docOrig = new XmlDocument(); 119 | docOrig.LoadXml(doc); 120 | return docOrig; 121 | } 122 | 123 | private static string ReadValue(XmlNode node, string defaultValue = "") 124 | { 125 | if (node != null) 126 | return node.InnerText; 127 | 128 | return defaultValue; 129 | } 130 | 131 | private string FormatSlug(XmlNode node) 132 | { 133 | return FormatterHelpers.FormatSlug(node.InnerText); 134 | } 135 | 136 | private IEnumerable FormatCategories(XmlNode catNode) 137 | { 138 | if (catNode == null || string.IsNullOrEmpty(catNode.InnerText)) 139 | yield break; 140 | 141 | string[] categories = catNode.InnerText.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); 142 | 143 | foreach (string category in categories) 144 | { 145 | yield return category; 146 | } 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Formatters/FormatterHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | 8 | namespace MiniBlogFormatter 9 | { 10 | public static class FormatterHelpers 11 | { 12 | public static string FormatSlug(string slug) 13 | { 14 | string text = slug.ToLowerInvariant().Replace(" ", "-"); 15 | return Regex.Replace(text, @"([^0-9a-z-\(\)])", string.Empty).Trim(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Formatters/GhostFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.IO; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text.RegularExpressions; 7 | using MiniBlogFormatter.Models; 8 | using Newtonsoft.Json; 9 | 10 | namespace MiniBlogFormatter.Formatters 11 | { 12 | public class GhostFormatter 13 | { 14 | private readonly Regex imageRegex = new Regex(@"/content/images/", RegexOptions.Compiled); 15 | 16 | public void Format(string jsonFilePath, string targetFolderPath) 17 | { 18 | FormatPosts(jsonFilePath, targetFolderPath); 19 | } 20 | 21 | private void FormatPosts(string jsonFilePath, string targetFolderPath) 22 | { 23 | var rawJsonData = File.ReadAllText(jsonFilePath); 24 | var ghostData = JsonConvert.DeserializeObject(rawJsonData); 25 | 26 | foreach (var ghostPost in ghostData.data.posts) 27 | { 28 | var post = new Post 29 | { 30 | Categories = GetPostCategories(ghostData, ghostPost).ToArray(), 31 | Title = ghostPost.title, 32 | Slug = ghostPost.slug, 33 | PubDate = ghostPost.published_at.HasValue ? ConvertFromUnixEpoch(ghostPost.published_at.Value) : DateTime.Now, 34 | LastModified = ghostPost.updated_at.HasValue ? ConvertFromUnixEpoch(ghostPost.updated_at.Value) : DateTime.Now, 35 | Content = FormatFileReferences(ghostPost.html), 36 | Author = GetPostAuthor(ghostData, ghostPost), 37 | IsPublished = ghostPost.published_at.HasValue 38 | }; 39 | 40 | var newFile = Path.Combine(targetFolderPath, ghostPost.uuid + ".xml"); 41 | Storage.Save(post, newFile); 42 | } 43 | } 44 | 45 | private static DateTime ConvertFromUnixEpoch(long unixTime) 46 | { 47 | var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); 48 | 49 | // We need to remove the last 3 digits of the unixtimeStamp otherwise it throws an overflow 50 | var timeStampString = unixTime.ToString(CultureInfo.CurrentCulture); 51 | timeStampString = timeStampString.Substring(0, timeStampString.Length - 3); 52 | var longTimestampFromString = long.Parse(timeStampString); 53 | 54 | return epoch.AddSeconds(longTimestampFromString); 55 | } 56 | 57 | private string FormatFileReferences(string content) 58 | { 59 | foreach (Match match in imageRegex.Matches(content)) 60 | { 61 | content = content.Replace(match.Groups[0].Value, "/posts/files/" ); 62 | } 63 | 64 | return content; 65 | } 66 | 67 | private static IEnumerable GetPostCategories(GhostData ghostData, GhostPost post) 68 | { 69 | var postCategoryIds = ghostData.data.posts_tags.Where(t => t.post_id == post.id).Select(c => c.tag_id).ToList(); 70 | return postCategoryIds.Select(id => ghostData.data.tags.FirstOrDefault(t => t.id == id).name).ToArray(); 71 | } 72 | 73 | private static string GetPostAuthor(GhostData ghostData, GhostPost post) 74 | { 75 | return ghostData.data.users.FirstOrDefault(u => u.id == post.created_by).name; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Formatters/WordpressFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Text.RegularExpressions; 5 | using System.Xml; 6 | using System.Linq; 7 | 8 | 9 | namespace MiniBlogFormatter 10 | { 11 | public class WordpressFormatter 12 | { 13 | private Regex rxFiles = new Regex("(href|src)=\"(([^\"]+)(/content/binary/)([^\"]+))\"", RegexOptions.IgnoreCase); 14 | 15 | public void Format(string originalFolderPath, string targetFolderPath) 16 | { 17 | FormatPosts(originalFolderPath, targetFolderPath); 18 | } 19 | 20 | private void FormatPosts(string originalFolderPath, string targetFolderPath) 21 | { 22 | foreach (string file in Directory.GetFiles(originalFolderPath, "*.xml")) 23 | { 24 | XmlDocument docOrig = LoadDocument(file); 25 | XmlNamespaceManager nsm = LoadNamespaceManager(docOrig); 26 | XmlNamespaceManager namespaceManager = new XmlNamespaceManager(docOrig.NameTable); 27 | namespaceManager.AddNamespace("content", docOrig.DocumentElement.GetNamespaceOfPrefix("content")); 28 | namespaceManager.AddNamespace("dc", docOrig.DocumentElement.GetNamespaceOfPrefix("dc")); 29 | namespaceManager.AddNamespace("wp", docOrig.DocumentElement.GetNamespaceOfPrefix("wp")); 30 | 31 | 32 | foreach (XmlNode entry in docOrig.SelectNodes("//item", nsm)) 33 | { 34 | Post post = new Post(); 35 | XmlNodeList categories = entry.SelectNodes("category[@domain='category']"); 36 | List resultCategories = new List(); 37 | foreach (XmlNode category in categories) 38 | { 39 | resultCategories.Add(category.InnerText); 40 | } 41 | 42 | post.Categories = resultCategories.ToArray(); 43 | post.Title = entry.SelectSingleNode("title").InnerText; 44 | post.Slug = FormatterHelpers.FormatSlug(post.Title); 45 | post.PubDate = DateTime.Parse(entry.SelectSingleNode("pubDate").InnerText); 46 | post.LastModified = DateTime.Parse(entry.SelectSingleNode("pubDate").InnerText); 47 | 48 | 49 | post.Content = FormatFileReferences(entry.SelectSingleNode("content:encoded", namespaceManager).InnerText); 50 | post.Author = entry.SelectSingleNode("dc:creator", namespaceManager).InnerText; 51 | post.IsPublished = ReadValue(entry.SelectSingleNode("wp:status", namespaceManager), "publish") == "publish"; 52 | 53 | // FormatComments() 54 | foreach (XmlNode comment in entry.SelectNodes("wp:comment", namespaceManager)) 55 | { 56 | FomartComment(ref post, comment, namespaceManager); 57 | } 58 | 59 | 60 | string newFile = Path.Combine(targetFolderPath, entry.SelectSingleNode("wp:post_id", namespaceManager).InnerText + ".xml"); 61 | Storage.Save(post, newFile); 62 | } 63 | } 64 | } 65 | 66 | private void FomartComment(ref Post post, XmlNode entry, XmlNamespaceManager namespaceManager) 67 | { 68 | Comment comment = new Comment(); 69 | comment.Author = ReadValue(entry.SelectSingleNode("wp:comment_author", namespaceManager), "n/a"); 70 | comment.Email = ReadValue(entry.SelectSingleNode("wp:comment_author_email", namespaceManager), ""); 71 | comment.Ip = entry.SelectSingleNode("wp:comment_author_IP", namespaceManager).InnerText; 72 | comment.Website = entry.SelectSingleNode("wp:comment_author_url", namespaceManager).InnerText; 73 | comment.Content = entry.SelectSingleNode("wp:comment_content", namespaceManager).InnerText; 74 | comment.PubDate = DateTime.Parse(ReadValue(entry.SelectSingleNode("wp:comment_date", namespaceManager), "")); 75 | comment.ID = entry.SelectSingleNode("wp:comment_id", namespaceManager).InnerText; 76 | comment.UserAgent = "n/a"; 77 | post.Comments.Add(comment); 78 | } 79 | 80 | private string FormatFileReferences(string content) 81 | { 82 | foreach (Match match in rxFiles.Matches(content)) 83 | { 84 | content = content.Replace(match.Groups[2].Value, "/posts/files/" + match.Groups[5].Value); 85 | } 86 | 87 | return content; 88 | } 89 | 90 | private static XmlNamespaceManager LoadNamespaceManager(XmlDocument docOrig) 91 | { 92 | XmlNamespaceManager nsm = new XmlNamespaceManager(docOrig.NameTable); 93 | nsm.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 94 | nsm.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema"); 95 | return nsm; 96 | } 97 | 98 | private static XmlDocument LoadDocument(string file) 99 | { 100 | string doc = File.ReadAllText(file).Replace(" xmlns=\"urn:newtelligence-com:dasblog:runtime:data\"", string.Empty); 101 | 102 | XmlDocument docOrig = new XmlDocument(); 103 | docOrig.LoadXml(doc); 104 | return docOrig; 105 | } 106 | 107 | private static string ReadValue(XmlNode node, string defaultValue = "") 108 | { 109 | if (node != null) 110 | return node.InnerText; 111 | 112 | return defaultValue; 113 | } 114 | 115 | private string FormatSlug(XmlNode node) 116 | { 117 | return FormatterHelpers.FormatSlug(node.InnerText); 118 | } 119 | 120 | private IEnumerable FormatCategories(XmlNode catNode) 121 | { 122 | if (catNode == null || string.IsNullOrEmpty(catNode.InnerText)) 123 | yield break; 124 | 125 | string[] categories = catNode.InnerText.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); 126 | 127 | foreach (string category in categories) 128 | { 129 | yield return category; 130 | } 131 | } 132 | 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /MiniBlogFormatter/MiniBlogFormatter.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B92EB6D7-8C50-481C-B68D-A7C04CAFF65C} 8 | Exe 9 | Properties 10 | MiniBlogFormatter 11 | MiniBlogFormatter 12 | v4.5.1 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | False 38 | ..\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 76 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Models/Comment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | public class Comment 4 | { 5 | public Comment() 6 | { 7 | ID = Guid.NewGuid().ToString(); 8 | PubDate = DateTime.UtcNow; 9 | } 10 | 11 | public string ID { get; set; } 12 | public string Author { get; set; } 13 | public string Email { get; set; } 14 | public string Website { get; set; } 15 | public string Content { get; set; } 16 | public DateTime PubDate { get; set; } 17 | public string Ip { get; set; } 18 | public string UserAgent { get; set; } 19 | public bool IsAdmin { get; set; } 20 | } -------------------------------------------------------------------------------- /MiniBlogFormatter/Models/GhostData.cs: -------------------------------------------------------------------------------- 1 | namespace MiniBlogFormatter.Models 2 | { 3 | public class GhostData 4 | { 5 | public Meta meta { get; set; } 6 | public Data data { get; set; } 7 | } 8 | 9 | public class Meta 10 | { 11 | public long exported_on { get; set; } 12 | public string version { get; set; } 13 | } 14 | 15 | public class Data 16 | { 17 | public GhostPost[] posts { get; set; } 18 | public User[] users { get; set; } 19 | public Role[] roles { get; set; } 20 | public Roles_Users[] roles_users { get; set; } 21 | public Permission[] permissions { get; set; } 22 | public object[] permissions_users { get; set; } 23 | public Permissions_Roles[] permissions_roles { get; set; } 24 | public Setting[] settings { get; set; } 25 | public Tag[] tags { get; set; } 26 | public Posts_Tags[] posts_tags { get; set; } 27 | } 28 | 29 | public class GhostPost 30 | { 31 | public int id { get; set; } 32 | public string uuid { get; set; } 33 | public string title { get; set; } 34 | public string slug { get; set; } 35 | public string markdown { get; set; } 36 | public string html { get; set; } 37 | public object image { get; set; } 38 | public int featured { get; set; } 39 | public int page { get; set; } 40 | public string status { get; set; } 41 | public string language { get; set; } 42 | public object meta_title { get; set; } 43 | public object meta_description { get; set; } 44 | public int? author_id { get; set; } 45 | public long? created_at { get; set; } 46 | public int? created_by { get; set; } 47 | public long? updated_at { get; set; } 48 | public int? updated_by { get; set; } 49 | public long? published_at { get; set; } 50 | public int? published_by { get; set; } 51 | } 52 | 53 | public class User 54 | { 55 | public int id { get; set; } 56 | public string uuid { get; set; } 57 | public string name { get; set; } 58 | public string slug { get; set; } 59 | public string password { get; set; } 60 | public string email { get; set; } 61 | public object image { get; set; } 62 | public object cover { get; set; } 63 | public string bio { get; set; } 64 | public string website { get; set; } 65 | public string location { get; set; } 66 | public object accessibility { get; set; } 67 | public string status { get; set; } 68 | public string language { get; set; } 69 | public object meta_title { get; set; } 70 | public object meta_description { get; set; } 71 | public object last_login { get; set; } 72 | public long? created_at { get; set; } 73 | public int? created_by { get; set; } 74 | public long? updated_at { get; set; } 75 | public int? updated_by { get; set; } 76 | } 77 | 78 | public class Role 79 | { 80 | public int id { get; set; } 81 | public string uuid { get; set; } 82 | public string name { get; set; } 83 | public string description { get; set; } 84 | public long? created_at { get; set; } 85 | public int? created_by { get; set; } 86 | public long? updated_at { get; set; } 87 | public int? updated_by { get; set; } 88 | } 89 | 90 | public class Roles_Users 91 | { 92 | public int id { get; set; } 93 | public int? role_id { get; set; } 94 | public int? user_id { get; set; } 95 | } 96 | 97 | public class Permission 98 | { 99 | public int id { get; set; } 100 | public string uuid { get; set; } 101 | public string name { get; set; } 102 | public string object_type { get; set; } 103 | public string action_type { get; set; } 104 | public object object_id { get; set; } 105 | public long? created_at { get; set; } 106 | public int? created_by { get; set; } 107 | public long? updated_at { get; set; } 108 | public int? updated_by { get; set; } 109 | } 110 | 111 | public class Permissions_Roles 112 | { 113 | public int id { get; set; } 114 | public int? role_id { get; set; } 115 | public int? permission_id { get; set; } 116 | } 117 | 118 | public class Setting 119 | { 120 | public int id { get; set; } 121 | public string uuid { get; set; } 122 | public string key { get; set; } 123 | public string value { get; set; } 124 | public string type { get; set; } 125 | public long? created_at { get; set; } 126 | public int? created_by { get; set; } 127 | public long? updated_at { get; set; } 128 | public int? updated_by { get; set; } 129 | } 130 | 131 | public class Tag 132 | { 133 | public int id { get; set; } 134 | public string uuid { get; set; } 135 | public string name { get; set; } 136 | public string slug { get; set; } 137 | public object description { get; set; } 138 | public object parent_id { get; set; } 139 | public object meta_title { get; set; } 140 | public object meta_description { get; set; } 141 | public long? created_at { get; set; } 142 | public int? created_by { get; set; } 143 | public long? updated_at { get; set; } 144 | public int? updated_by { get; set; } 145 | } 146 | 147 | public class Posts_Tags 148 | { 149 | public int id { get; set; } 150 | public int? post_id { get; set; } 151 | public int? tag_id { get; set; } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /MiniBlogFormatter/Models/Post.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Web; 4 | 5 | public class Post 6 | { 7 | public Post() 8 | { 9 | ID = Guid.NewGuid().ToString(); 10 | Title = "My new post"; 11 | Content = "the content"; 12 | PubDate = DateTime.UtcNow; 13 | LastModified = DateTime.UtcNow; 14 | Categories = new string[0]; 15 | Comments = new List(); 16 | IsPublished = true; 17 | } 18 | 19 | public string ID { get; set; } 20 | 21 | public string Title { get; set; } 22 | 23 | public string Author { get; set; } 24 | 25 | public string Slug { get; set; } 26 | 27 | public string Content { get; set; } 28 | 29 | public DateTime PubDate { get; set; } 30 | 31 | public DateTime LastModified { get; set; } 32 | 33 | public bool IsPublished { get; set; } 34 | 35 | public string[] Categories { get; set; } 36 | public List Comments { get; set; } 37 | } -------------------------------------------------------------------------------- /MiniBlogFormatter/Models/Storage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Web; 5 | using System.Xml.Linq; 6 | using System.Xml.XPath; 7 | 8 | public static class Storage 9 | { 10 | public static void Save(Post post, string file) 11 | { 12 | post.LastModified = DateTime.UtcNow; 13 | 14 | XDocument doc = new XDocument( 15 | new XElement("post", 16 | new XElement("title", post.Title), 17 | new XElement("slug", post.Slug), 18 | new XElement("author", post.Author), 19 | new XElement("pubDate", post.PubDate.ToString("yyyy-MM-dd HH:mm:ss")), 20 | new XElement("lastModified", post.LastModified.ToString("yyyy-MM-dd HH:mm:ss")), 21 | new XElement("content", post.Content), 22 | new XElement("ispublished", post.IsPublished), 23 | new XElement("categories", string.Empty), 24 | new XElement("comments", string.Empty) 25 | )); 26 | 27 | XElement categories = doc.XPathSelectElement("post/categories"); 28 | foreach (string category in post.Categories) 29 | { 30 | categories.Add(new XElement("category", category)); 31 | } 32 | 33 | XElement comments = doc.XPathSelectElement("post/comments"); 34 | foreach (Comment comment in post.Comments) 35 | { 36 | comments.Add( 37 | new XElement("comment", 38 | new XElement("author", comment.Author), 39 | new XElement("email", comment.Email), 40 | new XElement("website", comment.Website), 41 | new XElement("ip", comment.Ip), 42 | new XElement("userAgent", comment.UserAgent), 43 | new XElement("date", comment.PubDate.ToString("yyyy-MM-dd HH:m:ss")), 44 | new XElement("content", comment.Content), 45 | new XAttribute("isAdmin", comment.IsAdmin), 46 | new XAttribute("id", comment.ID) 47 | )); 48 | } 49 | 50 | doc.Save(file); 51 | } 52 | 53 | public static Post LoadPost(string file) 54 | { 55 | XElement doc = XElement.Load(file); 56 | 57 | Post post = new Post() 58 | { 59 | ID = Path.GetFileNameWithoutExtension(file), 60 | Title = ReadValue(doc, "title"), 61 | Author = ReadValue(doc, "author"), 62 | Content = ReadValue(doc, "content"), 63 | Slug = ReadValue(doc, "slug").ToLowerInvariant(), 64 | PubDate = DateTime.Parse(ReadValue(doc, "pubDate")), 65 | LastModified = DateTime.Parse(ReadValue(doc, "lastModified", DateTime.Now.ToString())), 66 | IsPublished = bool.Parse(ReadValue(doc, "ispublished", "true")), 67 | }; 68 | 69 | return post; 70 | } 71 | 72 | //private static void LoadCategories(Post post, XElement doc) 73 | //{ 74 | // XElement categories = doc.Element("categories"); 75 | // if (categories == null) 76 | // return; 77 | 78 | // List list = new List(); 79 | 80 | // foreach (var node in categories.Elements("category")) 81 | // { 82 | // list.Add(node.Value); 83 | // } 84 | 85 | // post.Categories = list.ToArray(); 86 | //} 87 | //private static void LoadComments(Post post, XElement doc) 88 | //{ 89 | // var comments = doc.Element("comments"); 90 | 91 | // if (comments == null) 92 | // return; 93 | 94 | // foreach (var node in comments.Elements("comment")) 95 | // { 96 | // Comment comment = new Comment() 97 | // { 98 | // ID = ReadAttribute(node, "id"), 99 | // Author = ReadValue(node, "author"), 100 | // Email = ReadValue(node, "email"), 101 | // Website = ReadValue(node, "website"), 102 | // Ip = ReadValue(node, "ip"), 103 | // UserAgent = ReadValue(node, "userAgent"), 104 | // IsAdmin = bool.Parse(ReadAttribute(node, "isAdmin", "false")), 105 | // Content = ReadValue(node, "content").Replace("\n", "
"), 106 | // PubDate = DateTime.Parse(ReadValue(node, "date", "2000-01-01")), 107 | // }; 108 | 109 | // post.Comments.Add(comment); 110 | // } 111 | //} 112 | 113 | private static string ReadValue(XElement doc, XName name, string defaultValue = "") 114 | { 115 | if (doc.Element(name) != null) 116 | return doc.Element(name).Value; 117 | 118 | return defaultValue; 119 | } 120 | 121 | private static string ReadAttribute(XElement element, XName name, string defaultValue = "") 122 | { 123 | if (element.Attribute(name) != null) 124 | return element.Attribute(name).Value; 125 | 126 | return defaultValue; 127 | } 128 | } -------------------------------------------------------------------------------- /MiniBlogFormatter/Program.cs: -------------------------------------------------------------------------------- 1 | using MiniBlogFormatter.Formatters; 2 | using System.IO; 3 | 4 | namespace MiniBlogFormatter 5 | { 6 | class Program 7 | { 8 | static void Main(string[] args) 9 | { 10 | // For BlogEngine.NET only 11 | var categories = @"C:\dev\MiniBlogFormatter\myblogposts"; 12 | 13 | // For both BlogEngine.NET and DasBlog 14 | //var origin = @"C:\Temp\GhostData.json"; 15 | //var destination = @"C:\Temp\Formatted"; 16 | 17 | 18 | //BlogEngine(categories, folder, destination); 19 | //Wordpress(origin, destination); 20 | 21 | //Ghost(origin, destination); 22 | 23 | // For BlogML 24 | var base64File = @"C:\Blog\BlogMLExport-b64.xml"; 25 | var origin = @"C:\dev\BlogMLExport.xml"; 26 | var destination = @"C:\dev\formatted"; 27 | BlogML(origin, destination, base64File); 28 | } 29 | 30 | static void BlogML(string file, string destination, string base64File = null) 31 | { 32 | var formatter = new BlogMLFormatter(); 33 | if (base64File != null) 34 | { 35 | formatter.ConvertFromBase64(base64File, file); 36 | } 37 | 38 | formatter.Format(file, destination); 39 | } 40 | 41 | private static void DasBlog(string folder, string destination) 42 | { 43 | var formatter = new DasBlogFormatter(); 44 | formatter.Format(folder, destination); 45 | } 46 | 47 | private static void Wordpress(string folder, string destination) 48 | { 49 | var formatter = new WordpressFormatter(); 50 | formatter.Format(folder, destination); 51 | } 52 | 53 | 54 | private static void BlogEngine(string categories, string folder, string destination) 55 | { 56 | var formatter = new BlogEngineFormatter(); 57 | foreach (string file in Directory.GetFiles(folder, "*.xml")) 58 | { 59 | formatter.Format(file, destination, categories); 60 | } 61 | } 62 | 63 | private static void Ghost(string folder, string destination) 64 | { 65 | var formatter = new GhostFormatter(); 66 | formatter.Format(folder, destination); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /MiniBlogFormatter/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MiniBlogFormatter 2 | ================= 3 | 4 | This is a console app for converting your existing blog to MiniBlog. 5 | 6 | Current platforms supported: 7 | 8 | * BlogEngine.NET 9 | * BlogML 10 | * DasBlog 11 | * Ghost 12 | * WordPress 13 | -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/Newtonsoft.Json.6.0.6.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/Newtonsoft.Json.6.0.6.nupkg -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/lib/net20/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/lib/net20/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/lib/net35/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/lib/net35/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/lib/net40/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/lib/net40/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/lib/net45/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/lib/net45/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/lib/netcore45/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/lib/netcore45/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/lib/portable-net45+wp80+win8+wpa81+aspnetcore50/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madskristensen/MiniBlogFormatter/c5f185f9641e5cdf6ef6a65588f9e13f08d0f2cc/packages/Newtonsoft.Json.6.0.6/lib/portable-net45+wp80+win8+wpa81+aspnetcore50/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /packages/Newtonsoft.Json.6.0.6/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | # open json.net splash page on package install 4 | # don't open if json.net is installed as a dependency 5 | 6 | try 7 | { 8 | $url = "http://james.newtonking.com/json" 9 | $dte2 = Get-Interface $dte ([EnvDTE80.DTE2]) 10 | 11 | if ($dte2.ActiveWindow.Caption -eq "Package Manager Console") 12 | { 13 | # user is installing from VS NuGet console 14 | # get reference to the window, the console host and the input history 15 | # show webpage if "install-package newtonsoft.json" was last input 16 | 17 | $consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow]) 18 | 19 | $props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor ` 20 | [System.Reflection.BindingFlags]::NonPublic) 21 | 22 | $prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1 23 | if ($prop -eq $null) { return } 24 | 25 | $hostInfo = $prop.GetValue($consoleWindow) 26 | if ($hostInfo -eq $null) { return } 27 | 28 | $history = $hostInfo.WpfConsole.InputHistory.History 29 | 30 | $lastCommand = $history | select -last 1 31 | 32 | if ($lastCommand) 33 | { 34 | $lastCommand = $lastCommand.Trim().ToLower() 35 | if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("newtonsoft.json")) 36 | { 37 | $dte2.ItemOperations.Navigate($url) | Out-Null 38 | } 39 | } 40 | } 41 | else 42 | { 43 | # user is installing from VS NuGet dialog 44 | # get reference to the window, then smart output console provider 45 | # show webpage if messages in buffered console contains "installing...newtonsoft.json" in last operation 46 | 47 | $instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor ` 48 | [System.Reflection.BindingFlags]::NonPublic) 49 | $consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor ` 50 | [System.Reflection.BindingFlags]::NonPublic) 51 | if ($instanceField -eq $null -or $consoleField -eq $null) { return } 52 | 53 | $instance = $instanceField.GetValue($null) 54 | if ($instance -eq $null) { return } 55 | 56 | $consoleProvider = $consoleField.GetValue($instance) 57 | if ($consoleProvider -eq $null) { return } 58 | 59 | $console = $consoleProvider.CreateOutputConsole($false) 60 | 61 | $messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor ` 62 | [System.Reflection.BindingFlags]::NonPublic) 63 | if ($messagesField -eq $null) { return } 64 | 65 | $messages = $messagesField.GetValue($console) 66 | if ($messages -eq $null) { return } 67 | 68 | $operations = $messages -split "==============================" 69 | 70 | $lastOperation = $operations | select -last 1 71 | 72 | if ($lastOperation) 73 | { 74 | $lastOperation = $lastOperation.ToLower() 75 | 76 | $lines = $lastOperation -split "`r`n" 77 | 78 | $installMatch = $lines | ? { $_.StartsWith("------- installing...newtonsoft.json ") } | select -first 1 79 | 80 | if ($installMatch) 81 | { 82 | $dte2.ItemOperations.Navigate($url) | Out-Null 83 | } 84 | } 85 | } 86 | } 87 | catch 88 | { 89 | # stop potential errors from bubbling up 90 | # worst case the splash page won't open 91 | } 92 | 93 | # yolo --------------------------------------------------------------------------------