Last active
August 29, 2015 14:04
-
-
Save paulryan/e461f8bac28336b05109 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// | |
// Pleast note that this code should be used as example code only, it is not properly tested. | |
// | |
public class DeploymentActionImportTaxonomy : DeploymentAction<bool> | |
{ | |
public enum ImportTaxonomyMode | |
{ | |
DeleteAndRecreate, | |
OnlyAddNew | |
} | |
public DeploymentActionImportTaxonomy(ClientContext context, string termGroupName, string csvFolderPath, ImportTaxonomyMode mode, bool verbose) | |
: base(context, "Importing taxonomy", verbose) | |
{ | |
this.TermGroupName = termGroupName; | |
this.CsvFolderPath = csvFolderPath; | |
this.Mode = mode; | |
} | |
protected string TermGroupName { get; set; } | |
protected string CsvFolderPath { get; set; } | |
protected ImportTaxonomyMode Mode { get; set; } | |
protected override bool Action() | |
{ | |
// Get the xml files to import | |
string[] filePaths = null; | |
try | |
{ | |
filePaths = Directory.GetFiles(this.CsvFolderPath, "*.csv"); | |
} | |
catch (Exception ex) | |
{ | |
this.Print(string.Format("Failed to read from folder '{0}'. {1}", this.CsvFolderPath, ex.Message)); | |
throw ex; | |
} | |
if(filePaths == null || !filePaths.Any()) | |
{ | |
// Nothing to import | |
this.Print("No csv files found to import in folder: " + this.CsvFolderPath); | |
return false; | |
} | |
// Get the term group into which we are importing | |
var taxonomySession = TaxonomySession.GetTaxonomySession(this.Context); | |
var termStore = taxonomySession.GetDefaultSiteCollectionTermStore(); | |
var termGroup = termStore.GetSiteCollectionGroup(this.Context.Site, true); | |
termGroup.Name = this.TermGroupName; | |
this.Context.Load(termGroup); | |
this.Context.ExecuteQuery(); | |
// Import each xml file | |
foreach(var filePath in filePaths) | |
{ | |
string filename = filePath.Split('\\', '/').Last(); | |
this.Print(""); | |
this.Print("Importing taxonomy from: " + filename); | |
// Read file to string | |
string[] csvLines = null; | |
try | |
{ | |
csvLines = System.IO.File.ReadAllLines(filePath); | |
} | |
catch (Exception ex) | |
{ | |
this.Print("Failed to read from file. " + ex.Message); | |
break; | |
} | |
// Import the content | |
if (csvLines == null || csvLines.Length < 2) | |
{ | |
this.Print("Nothing to import. The header line plus at least a single content line is required."); | |
} | |
else if (string.IsNullOrEmpty(csvLines.First()) || !csvLines.First().StartsWith(Constants.Taxonomy.CsvImportFirstLine)) | |
{ | |
this.Print("CSV is badly formed. First line should be: " + Constants.Taxonomy.CsvImportFirstLine); | |
} | |
else | |
{ | |
// Import the lines (skipping the header line) | |
TermSet currentTermSet = null; | |
for (int i = 1; i < csvLines.Length; i++) | |
{ | |
var csvLine = csvLines[i]; | |
ImportCsvLine(termGroup, ref currentTermSet, csvLine); | |
} | |
} | |
} | |
return true; | |
} | |
private void ImportCsvLine(TermGroup termGroup, ref TermSet currentTermSet, string csvLineString) | |
{ | |
if (string.IsNullOrEmpty(csvLineString)) | |
{ | |
this.Print("Encountered an empty content line"); | |
} | |
else | |
{ | |
var csvLineStringArray = GenericUtil.CsvSplit(csvLineString); | |
if (csvLineStringArray.Length < 12) | |
{ | |
this.Print("A content line must contain at least 12 parts. e.g. " + Constants.Taxonomy.CsvImportFirstLine); | |
} | |
else | |
{ | |
var csvLine = new TaxonomyImportCsvLine(csvLineStringArray); | |
currentTermSet = GetCurrentTermSet(termGroup, currentTermSet, csvLine); | |
Term term = GetOrCreateTerm(currentTermSet, csvLine, null, 1); | |
} | |
} | |
} | |
private Term GetOrCreateTerm(TermSet currentTermSet, TaxonomyImportCsvLine csvLine, Term parentTerm, uint termLevel) | |
{ | |
string termName = csvLine.GetTermName(termLevel); | |
if (!string.IsNullOrEmpty(termName)) | |
{ | |
Term term = null; | |
if (parentTerm == null) | |
{ | |
term = currentTermSet.Terms.TryGetTerm(termName); | |
} | |
else | |
{ | |
term = parentTerm.Terms.TryGetTerm(termName); | |
} | |
if (term == null) | |
{ | |
this.Print("Creating term: " + termName); | |
if (parentTerm == null) | |
{ | |
term = currentTermSet.CreateTerm(termName, (int)csvLine.LCID, Guid.NewGuid()); | |
} | |
else | |
{ | |
term = parentTerm.CreateTerm(termName, (int)csvLine.LCID, Guid.NewGuid()); | |
} | |
term.SetDescription(csvLine.TermDescription, (int)csvLine.LCID); | |
this.Context.Load(term); | |
try | |
{ | |
this.Context.ExecuteQuery(); | |
} | |
catch (ServerException ex) | |
{ | |
//if(ex.ServerErrorTypeName == TaxonomyOperationException) | |
this.Print("Failed to create term: " + termName + ". " + ex.Message); | |
return null; | |
} | |
} | |
// Recursive call to next level | |
term = GetOrCreateTerm(currentTermSet, csvLine, term, (termLevel + 1)); | |
return term; | |
} | |
else | |
{ | |
return parentTerm; | |
} | |
} | |
private TermSet GetCurrentTermSet(TermGroup termGroup, TermSet currentTermSet, TaxonomyImportCsvLine csvLine) | |
{ | |
if (currentTermSet != null) | |
{ | |
bool usingPreviousTermSet = csvLine.AssignTermSetNameIfNullOrEmpty(currentTermSet.Name); | |
if (!usingPreviousTermSet) | |
{ | |
// Get or create term set | |
currentTermSet = GetOrCreateTermSet(termGroup, csvLine); | |
} | |
else | |
{ | |
// Do nothing, continue using the current term set | |
} | |
} | |
else | |
{ | |
if (string.IsNullOrEmpty(csvLine.TermSetName)) | |
{ | |
this.Print("Term set has not been defined"); | |
} | |
else | |
{ | |
// Get or create term set | |
currentTermSet = GetOrCreateTermSet(termGroup, csvLine); | |
} | |
} | |
return currentTermSet; | |
} | |
private TermSet GetOrCreateTermSet(TermGroup termGroup, TaxonomyImportCsvLine csvLine) | |
{ | |
TermSet termSet = termGroup.TermSets.TryGetTermSet(csvLine.TermSetName); | |
if (termSet != null && this.Mode == ImportTaxonomyMode.DeleteAndRecreate) | |
{ | |
this.Print("Deleting existing term set: " + termSet.Name); | |
termSet.DeleteObject(); | |
this.Context.Load(termSet); | |
this.Context.ExecuteQuery(); | |
termSet = null; | |
} | |
if(termSet == null) | |
{ | |
this.Print("Creating term set: " + csvLine.TermSetName); | |
termSet = termGroup.CreateTermSet(csvLine.TermSetName, Guid.NewGuid(), (int)csvLine.LCID); | |
termSet.Description = csvLine.TermSetDescription; | |
this.Context.Load(termSet); | |
this.Context.ExecuteQuery(); | |
} | |
return termSet; | |
} | |
public class TaxonomyImportCsvLine | |
{ | |
public TaxonomyImportCsvLine(string[] properties) | |
{ | |
this.TermSetName = properties[0]; | |
this.TermSetDescription = properties[1]; | |
this.AvailableForTagging = properties[3]; | |
this.TermDescription = properties[4]; | |
this.TermNames = new string[7]; | |
this.TermNames[0] = properties[5]; | |
this.TermNames[1] = properties[6]; | |
this.TermNames[2] = properties[7]; | |
this.TermNames[3] = properties[8]; | |
this.TermNames[4] = properties[9]; | |
this.TermNames[5] = properties[10]; | |
this.TermNames[6] = properties[11]; | |
uint lcid; | |
if (uint.TryParse(properties[2], out lcid)) | |
{ | |
this.LCID = lcid; | |
} | |
else | |
{ | |
this.LCID = Constants.Locales.Lcid.English_USA; | |
} | |
} | |
public string TermSetName { get; private set; } | |
public string TermSetDescription { get; private set; } | |
public uint LCID { get; private set; } | |
public string AvailableForTagging { get; private set; } | |
public string TermDescription { get; private set; } | |
private string[] TermNames { get; set; } | |
public bool AssignTermSetNameIfNullOrEmpty(string previousTermSetName) | |
{ | |
if (string.IsNullOrEmpty(this.TermSetName)) | |
{ | |
this.TermSetName = previousTermSetName; | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
public string GetTermName(uint level) | |
{ | |
if(level < 1 || level > 7) | |
{ | |
throw new Exception("Can only get terms of level 1 through to 7"); | |
} | |
var termNameAsProvided = this.TermNames[level - 1]; | |
var cleanTermName = Regex.Replace(termNameAsProvided, "[^a-zA-Z0-9_ -]+", string.Empty); | |
return termNameAsProvided; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment