Last active
March 8, 2022 15:07
-
-
Save borsna/34f5af4e74db968071381a1e473907e7 to your computer and use it in GitHub Desktop.
Simple C# script to create a ro-crate manifest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Text.Json; | |
using System.Text.Json.Nodes; | |
using System.Collections.Generic; | |
using System.Security.Cryptography; | |
using HeyRed.Mime; | |
if(Environment.GetCommandLineArgs().Length == 1){ | |
Console.WriteLine("Provide argument for directory"); | |
Environment.Exit(0); | |
} | |
string directory = Environment.GetCommandLineArgs()[1]; | |
directory = Path.GetFullPath(directory); | |
if (!Directory.Exists(directory)) | |
{ | |
Console.WriteLine("The directory specified could not be found."); | |
Environment.Exit(0); | |
} | |
var graph = new List<JsonNode>(); | |
graph.Add(new JsonObject { | |
["@type"] = "CreativeWork", | |
["@id"] = "ro-crate-metadata.json", | |
["conformsTo"] = new JsonObject { | |
["@id"] = "https://w3id.org/ro/crate/1.1" | |
}, | |
["about"] = new JsonObject { | |
["@id"] = "./" | |
}, | |
["publisher"] = new JsonObject { | |
["@type"] = "Organization", | |
["@id"] = "https://ror.org/01tm6cn81", //optional: from config/external source | |
["identifier"] = new JsonArray( | |
new JsonObject { | |
["@type"] = "PropertyValue", | |
["propertyID"] = "domain", | |
["propertyValue"] = "gu.se" //required: from config/external source | |
} | |
) | |
}, | |
["creator"] = new JsonArray( | |
new JsonObject { | |
["@type"] = "Person", | |
["@id"] = "https://orcid.org/0000-0003-4908-2169", //optional: from config/external source | |
["email"] = "[email protected]", | |
["identifier"] = new JsonArray( | |
new JsonObject { | |
["@type"] = "PropertyValue", | |
["propertyID"] = "eppn", | |
["propertyValue"] = "[email protected]" //required: from config/external source | |
} | |
) | |
} | |
) | |
}); | |
var dir = new DirectoryInfo(directory); | |
FileInfo[] files = dir.GetFiles("*", SearchOption.AllDirectories); | |
var fileIds = new List<JsonNode>(); | |
foreach (FileInfo fInfo in files){ | |
fileIds.Add(new JsonObject{ | |
["@id"] = fInfo.FullName.Replace(directory, "").Replace("\\","/") | |
}); | |
} | |
graph.Add(new JsonObject { | |
["@type"] = "Dataset", | |
["@id"] = "./", | |
["hasPart"] = new JsonArray(fileIds.ToArray()) | |
}); | |
using (SHA256 sha256 = SHA256.Create()) | |
{ | |
foreach (FileInfo fInfo in files) | |
{ | |
using (FileStream fileStream = fInfo.Open(FileMode.Open)) | |
{ | |
try | |
{ | |
fileStream.Position = 0; | |
byte[] hashValue = sha256.ComputeHash(fileStream); | |
graph.Add(new JsonObject { | |
["@type"] = "File", | |
["@id"] = fInfo.FullName.Replace(directory, "").Replace("\\","/"), | |
["sha256"] = byteToString(hashValue), | |
["contentSize"] = fInfo.Length, | |
["encodingFormat"] = MimeTypesMap.GetMimeType(fInfo.Name), | |
["dateCreated"] = File.GetCreationTime(fInfo.FullName).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.sssZ"), | |
["dateModified"] = File.GetLastWriteTime(fInfo.FullName).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.sssZ"), | |
}); | |
} | |
catch (IOException e) | |
{ | |
Console.WriteLine($"I/O Exception: {e.Message}"); | |
} | |
catch (UnauthorizedAccessException e) | |
{ | |
Console.WriteLine($"Access Exception: {e.Message}"); | |
} | |
} | |
} | |
} | |
var roCrateJson = new JsonObject { | |
["@context"] = "https://w3id.org/ro/crate/1.1/context", | |
["@graph"] = new JsonArray(graph.ToArray()) | |
}; | |
Console.Write(roCrateJson.ToJsonString(new JsonSerializerOptions { WriteIndented = true })); | |
string byteToString(byte[] array) | |
{ | |
string result = ""; | |
for (int i = 0; i < array.Length; i++) | |
{ | |
result += $"{array[i]:X2}"; | |
} | |
return result.ToLower(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment