Advertisement
commodore73

Contentstack .NET Static Site Exporter

Apr 11th, 2021 (edited)
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.51 KB | None | 0 0
  1. namespace cscrawl
  2. {
  3.     using Contentstack.Core;
  4.     using Contentstack.Core.Configuration;
  5.     using Contentstack.Core.Internals;
  6.     using Contentstack.Core.Models;
  7.     using Newtonsoft.Json.Linq;
  8.     using System;
  9.     using System.Collections.Generic;
  10.     using System.IO;
  11.     using System.Net;
  12.  
  13.     public class Program
  14.     {
  15.         static void Main(string[] args)
  16.         {
  17.             string output = "C:\\temp\\export"; //TODO: config
  18.             string urlPrefix = "https://localhost:44342"; //TODO: config
  19.             ContentstackClient stack = new ContentstackClient(
  20.                 new ContentstackOptions()
  21.                 {
  22.                     ApiKey = "//TODO: config", //TODO: config
  23.                     DeliveryToken = "//TODO: config", //TODO: config
  24.                     Environment = "//TODO: config" //TODO: config
  25.                 });
  26.  
  27.             // retrieve content types and entries in pages of 100 records
  28.             int pageSize = 100;
  29.  
  30.             // the number of content type records processed (for paging)
  31.             int contentTypesProcessed = 0;
  32.  
  33.             // if there are no records in the current page, then there are no more pages
  34.             bool moreContentTypesMayExist = false;
  35.  
  36.             // iterate pages of content type records
  37.             do
  38.             {
  39.                 // control content type paging
  40.                 Dictionary<string, object> contentTypePageParameters = new Dictionary<string, object>();
  41.                 contentTypePageParameters["skip"] = contentTypesProcessed;
  42.                 contentTypePageParameters["limit"] = pageSize;
  43.  
  44.                 try
  45.                 {
  46.                     // for each content type in this page of content types
  47.                     foreach (JObject contentTypeJson in
  48.                         stack.GetContentTypes(contentTypePageParameters).Result)
  49.                     {
  50.                         // number of entries of this content type processed (for paging)
  51.                         int entriesProcessed = 0;
  52.  
  53.                         // if there are no records in the current page, then there are no more pages
  54.                         bool moreEntriesMayExist = false;
  55.                         ContentType contentType = stack.ContentType(contentTypeJson["uid"].ToString());
  56.  
  57.                         // iterate pages of entry records
  58.                         do
  59.                         {
  60.                             // control entry paging
  61.                             Dictionary<string, object> entryPageParameters = new Dictionary<string, object>();
  62.                             entryPageParameters["skip"] = entriesProcessed;
  63.                             entryPageParameters["limit"] = pageSize;
  64.                             Query query = contentType.Query().Skip(entriesProcessed).Limit(pageSize);
  65.  
  66.                             // if there are no records in the page, then there are no more pages
  67.                             moreEntriesMayExist = false;
  68.  
  69.                             // for each entry in this page of this content type
  70.                             foreach (Entry entry in query.Find<Entry>().Result)
  71.                             {
  72.                                 entriesProcessed++;
  73.                                 moreEntriesMayExist = true;
  74.  
  75.                                 // ignore entries that do not have URLs
  76.                                 if (!entry.Object.ContainsKey("url"))
  77.                                 {
  78.                                     continue;
  79.                                 }
  80.  
  81.                                 string url = entry.Object["url"].ToString();
  82.  
  83.                                 // ignore entries with URLs that do not appear to be file paths
  84.                                 if (String.IsNullOrWhiteSpace(url)
  85.                                     || !url.StartsWith("/"))
  86.                                 {
  87.                                     continue;
  88.                                 }
  89.  
  90.                                 // path to filename to create, without extension
  91.                                 FileInfo fileInfo = new FileInfo(output + url.Replace("/", "\\"));
  92.  
  93.                                 // if a directory exists at that path,
  94.                                 // then the file should be index.html (home page) in that directory
  95.                                 if (Directory.Exists(fileInfo.FullName))
  96.                                 {
  97.                                     fileInfo = new FileInfo(fileInfo.FullName + "\\index");
  98.                                 }
  99.  
  100.                                 // create directory if required
  101.                                 if (!Directory.Exists(fileInfo.Directory.FullName))
  102.                                 {
  103.                                     Directory.CreateDirectory(fileInfo.Directory.FullName);
  104.                                 }
  105.  
  106.                                 // download the page, write the HTML and JSON to files
  107.                                 WebClient wc = new WebClient();
  108.                                 File.WriteAllBytes(fileInfo.FullName + ".html", wc.DownloadData(urlPrefix + url));
  109.                                 File.WriteAllText(fileInfo.FullName + ".json", entry.ToJson().ToString());
  110.                             }
  111.                         }
  112.                         while (entriesProcessed % pageSize == 0 && moreEntriesMayExist);
  113.                     }
  114.  
  115.                     contentTypesProcessed++;
  116.                 }
  117.                 catch (Exception ex)
  118.                 {
  119.                     Exception originalException = ex;
  120.  
  121.                     while (ex != null)
  122.                     {
  123.                         WebException wex = ex as WebException;
  124.  
  125.                         if (wex != null && wex.Response != null)
  126.                         {
  127.                             using (var stream = wex.Response.GetResponseStream())
  128.                             {
  129.                                 using (var reader = new StreamReader(stream))
  130.                                 {
  131.                                     Console.WriteLine(wex.GetType() + " : " + wex.Message);
  132.                                     Console.WriteLine(reader.ReadToEnd());
  133.                                     Console.WriteLine(wex.StackTrace);
  134.                                 }
  135.                             }
  136.  
  137.                             throw;
  138.                         }
  139.  
  140.                         ContentstackException cex = ex as ContentstackException;
  141.  
  142.                         if (cex != null)
  143.                         {
  144.                             Console.WriteLine(cex.GetType() + " : " + cex.Message);
  145.                             Console.WriteLine("Error code: " + cex.ErrorCode);
  146.                             Console.WriteLine("Error message: " + cex.ErrorMessage);
  147.                             Console.WriteLine("Status code: " + cex.StatusCode);
  148.  
  149.                             foreach (string key in cex.Errors.Keys)
  150.                             {
  151.                                 Console.WriteLine("Error : " + key + " : " + cex.Errors[key]);
  152.                             }
  153.  
  154.                             Console.WriteLine(cex.StackTrace);
  155.  
  156.                             throw;
  157.                         }
  158.  
  159.                         Console.WriteLine(originalException.GetType() + " : " + originalException.Message);
  160.                         Console.WriteLine(originalException.StackTrace);
  161.                         ex = ex.InnerException;
  162.                     }
  163.  
  164.                     throw;
  165.                 }
  166.             }
  167.             while (contentTypesProcessed % pageSize == 0 && moreContentTypesMayExist);
  168.  
  169.             RenameFiles(new DirectoryInfo(output));
  170.         }
  171.  
  172.         // recursive: for directory (/) and descendants (/child, /child/grandchild, etc),
  173.         // if corresponding .html and .json files (/child.html and /child.json) exist,
  174.         // then rename and move them to index files in that directory (/child/index.html and /child/index.json).
  175.         private static void RenameFiles(DirectoryInfo directory)
  176.         {
  177.             if (File.Exists(directory.FullName + ".html")
  178.                 && File.Exists(directory.FullName + ".json"))
  179.             {
  180.                 File.Move(directory + ".html", directory.FullName + "\\index.html", true /*overwrite*/ );
  181.                 File.Move(directory + ".json", directory.FullName + "\\index.json", true /*overwrite*/ );
  182.             }
  183.  
  184.             foreach (DirectoryInfo subdirectory in directory.GetDirectories())
  185.             {
  186.                 RenameFiles(subdirectory);
  187.             }
  188.         }
  189.     }
  190. }
  191.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement