Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/BloomExe/Book/AppearanceSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,14 @@ public string GetThemeAndSubstituteCss(Tuple<string, string>[] cssFilesToCheck)
// if we don't know of a substitute theme and its associated customBookStyles2.css file.
CssThemeName = "default";
string substituteAppearance = null;
if (Program.RunningHarvesterMode)
{
// We'll preserve the current appearance of older books we are harvesting.
// This should only apply to temporary copies on their way to becoming artifacts,
// so it doesn't interfere with getting books migrated when they are to be edited.
CssThemeName = "legacy-5-6";
return null;
}

foreach (var css in cssFilesToCheck.Where(css => !string.IsNullOrWhiteSpace(css.Item2)))
{
Expand Down
7 changes: 2 additions & 5 deletions src/BloomExe/Book/BookServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ public BookServer(
_tcManager = tcManager;
}

public virtual Book GetBookFromBookInfo(
BookInfo bookInfo,
bool fullyUpdateBookFiles = false
)
public virtual Book GetBookFromBookInfo(BookInfo bookInfo)
{
//Review: Note that this isn't doing any caching yet... worried that caching will just eat up memory, but if anybody is holding onto these, then the memory won't be freed anyhow
if (bookInfo is ErrorBookInfo)
Expand All @@ -45,7 +42,7 @@ public virtual Book GetBookFromBookInfo(
);
}

var book = _bookFactory(bookInfo, _storageFactory(bookInfo, fullyUpdateBookFiles));
var book = _bookFactory(bookInfo, _storageFactory(bookInfo));
return book;
}

Expand Down
15 changes: 14 additions & 1 deletion src/BloomExe/Book/BookStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Tuple<string, string>[] GetCssFilesToCheckForAppearanceCompatibility(

public class BookStorage : IBookStorage
{
public delegate BookStorage Factory(BookInfo bookInfo, bool fullyUpdateBookFiles = false); //autofac uses this
public delegate BookStorage Factory(BookInfo bookInfo); //autofac uses this

/// <summary>
/// History of these numbers:
Expand Down Expand Up @@ -3684,6 +3684,12 @@ public string[] getMinimalCssFilesFromInstallThatDoNotChangeAtRuntime()
/// </summary>
public bool LinkToLocalCollectionStyles { get; set; }

public class CannotHarvestException : ApplicationException
{
public CannotHarvestException(string message)
: base(message) { }
}

/// <summary>
/// Migrate to the new appearance system if we haven't already tried to do so.
/// </summary>
Expand All @@ -3696,6 +3702,13 @@ public void MigrateToLevel4UseAppearanceSystem()
if (GetMaintenanceLevel() >= 4)
return;

if (Program.RunningHarvesterMode && !LegacyThemeCanBeUsed)
{
throw new CannotHarvestException(
"This book cannot currently be harvested, since it is not migrated to the appearance system and cannot use legacy theme."
);
}

var cssFiles = GetCssFilesToCheckForAppearanceCompatibility(true);
var substituteCssPath = BookInfo.AppearanceSettings.GetThemeAndSubstituteCss(cssFiles);
if (substituteCssPath != null)
Expand Down
23 changes: 19 additions & 4 deletions src/BloomExe/CLI/CreateArtifactsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ enum CreateArtifactsExitCode
Success = 0,
UnhandledException = 1,
BookHtmlNotFound = 2,
EpubException = 4
EpubException = 4,
LegacyBookCannotHarvest = 8
}

class CreateArtifactsCommand
Expand Down Expand Up @@ -61,6 +62,12 @@ public static List<string> GetErrorsFromExitCode(int exitCode)
exitCode &= ~(int)CreateArtifactsExitCode.EpubException;
}

if ((exitCode & (int)CreateArtifactsExitCode.LegacyBookCannotHarvest) != 0)
{
errors.Add(CreateArtifactsExitCode.LegacyBookCannotHarvest.ToString());
exitCode &= ~(int)CreateArtifactsExitCode.LegacyBookCannotHarvest;
}

// Check if:
// 1) Some error code was found
// 2) No unknown flags remain
Expand All @@ -71,6 +78,11 @@ public static List<string> GetErrorsFromExitCode(int exitCode)
}

public static Task<int> Handle(CreateArtifactsParameters options)
{
return Task.FromResult((int)HandleInternal(options));
}

internal static CreateArtifactsExitCode HandleInternal(CreateArtifactsParameters options)
{
try
{
Expand Down Expand Up @@ -103,15 +115,18 @@ public static Task<int> Handle(CreateArtifactsParameters options)
Bloom.Program.SetProjectContext(_projectContext);

// Make the .bloompub and /bloomdigital outputs
var exitCode = CreateArtifacts(options);
return Task.FromResult((int)exitCode);
return CreateArtifacts(options);
}
}
}
catch (BookStorage.CannotHarvestException)
{
return CreateArtifactsExitCode.LegacyBookCannotHarvest;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return Task.FromResult((int)CreateArtifactsExitCode.UnhandledException);
return CreateArtifactsExitCode.UnhandledException;
}
}

Expand Down
11 changes: 8 additions & 3 deletions src/BloomExe/CollectionTab/CollectionModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,17 @@ public string LanguageName

private object _bookCollectionLock = new object(); // Locks creation of _bookCollections

public IReadOnlyList<BookCollection> GetBookCollections()
public IReadOnlyList<BookCollection> GetBookCollections(bool disposing = false)
{
lock (_bookCollectionLock)
{
if (_bookCollections == null)
{
if (disposing)
{
// We don't want to create new collections when we're disposing of the model.
return new List<BookCollection>();
}
_bookCollections = new List<BookCollection>(GetBookCollectionsOnce());

//we want the templates to be second (after the editable collection) regardless of alphabetical sorting
Expand Down Expand Up @@ -999,14 +1004,14 @@ public BookInfo GetBookInfoByFolderPath(string path)
return collection.GetBookInfoByFolderPath(path);
}

public Book.Book GetBookFromBookInfo(BookInfo bookInfo, bool fullyUpdateBookFiles = false)
public Book.Book GetBookFromBookInfo(BookInfo bookInfo)
{
// If we're looking for the current book it's important to return the actual book object,
// because it could end up modified in ways that make our one out-of-date if we modify another
// instance based on the same folder. For example, Rename could make our FolderPath wrong.
if (bookInfo.FolderPath == _bookSelection.CurrentSelection?.FolderPath)
return _bookSelection.CurrentSelection;
return _bookServer.GetBookFromBookInfo(bookInfo, fullyUpdateBookFiles);
return _bookServer.GetBookFromBookInfo(bookInfo);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/BloomExe/CollectionTab/CollectionTabView.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/BloomExe/CollectionTab/CollectionTabView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ private void OnBookCollectionCreated(object collection, EventArgs args)
// One day we may enhance it so that we switch tabs and show it,
// but there are states where that would be dangerous.
var newBook = new BookInfo(eventArgs.Path, false);
var book = _model.GetBookFromBookInfo(newBook, true);
var book = _model.GetBookFromBookInfo(newBook);
if (string.IsNullOrEmpty(book.Storage.ErrorMessagesHtml))
{
// Happy path. Usually we can make a book object out of a downloaded book folder.
Expand All @@ -223,7 +223,7 @@ private void OnBookCollectionCreated(object collection, EventArgs args)
t.Tick += (o, args1) =>
{
retries++;
book = _model.GetBookFromBookInfo(newBook, true);
book = _model.GetBookFromBookInfo(newBook);
if (string.IsNullOrEmpty(book.Storage.ErrorMessagesHtml))
{
t.Stop();
Expand Down
7 changes: 5 additions & 2 deletions src/BloomExe/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1734,7 +1734,7 @@ internal static void SetUpErrorHandling()
if (_errorHandlingHasBeenSetUp)
return;

if (!ApplicationUpdateSupport.IsDev)
if (!ApplicationUpdateSupport.IsDev && !Program.RunningUnitTests)
{
try
{
Expand Down Expand Up @@ -1803,8 +1803,11 @@ internal static void SetUpErrorHandling()
SIL.Reporting.ErrorReport.AddStandardProperties();
// with squirrel, the file's dates only reflect when they were installed, so we override this version thing which
// normally would include a bogus "Apparently Built On" date:
var versionNumber = Program.RunningUnitTests
? "Current build" // for some reason VersionNumberString throws when running unit tests, so just use this.
: ErrorReport.VersionNumberString;
ErrorReport.Properties["Version"] =
ErrorReport.VersionNumberString + " " + ApplicationUpdateSupport.ChannelName;
versionNumber + " " + ApplicationUpdateSupport.ChannelName;
SIL.Reporting.ExceptionHandler.Init(new FatalExceptionHandler());

ExceptionHandler.AddDelegate(
Expand Down
2 changes: 1 addition & 1 deletion src/BloomExe/WebLibraryIntegration/BulkUploader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ ref ProjectContext context
context.TeamCollectionManager.CurrentCollectionEvenIfDisconnected
?? new AlwaysEditSaveContext() as ISaveContext
);
var book = server.GetBookFromBookInfo(bookInfo, fullyUpdateBookFiles: true);
var book = server.GetBookFromBookInfo(bookInfo);
book.BringBookUpToDate(new NullProgress());
uploadParams.Folder = book.FolderPath; // BringBookUpToDate can change the title and folder (see BL-10330)
book.Storage.CleanupUnusedSupportFiles(isForPublish: false); // we are publishing, but this is the real folder not a copy, so play safe.
Expand Down
2 changes: 1 addition & 1 deletion src/BloomExe/Workspace/WorkspaceView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ private void SelectBookAtStartup()
//var info = new BookInfo(selBookPath, inCurrentCollection, _tcManager.CurrentCollectionEvenIfDisconnected ?? new AlwaysEditSaveContext() as ISaveContext);
// Fully updating book files ensures that the proper branding files are found for
// previewing when the collection settings change but the book selection does not.
var book = _bookServer.GetBookFromBookInfo(info, fullyUpdateBookFiles: true);
var book = _bookServer.GetBookFromBookInfo(info);
_bookSelection.SelectBook(book);
}
}
Expand Down
11 changes: 4 additions & 7 deletions src/BloomExe/web/controllers/CollectionApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public void RegisterWithApiHandler(BloomApiHandler apiHandler)
kApiUrlPart + "selectAndEditBook",
request =>
{
var book = GetBookObjectFromPost(request, true);
var book = GetBookObjectFromPost(request);
if (book.FolderPath != _bookSelection?.CurrentSelection?.FolderPath)
{
_collectionModel.SelectBook(book);
Expand Down Expand Up @@ -781,18 +781,15 @@ private BookInfo GetBookInfoFromPost(ApiRequest request)
return collection.GetBookInfos().FirstOrDefault(predicate);
}

private Book.Book GetBookObjectFromPost(
ApiRequest request,
bool fullyUpdateBookFiles = false
)
private Book.Book GetBookObjectFromPost(ApiRequest request)
{
var info = GetBookInfoFromPost(request);
return _collectionModel.GetBookFromBookInfo(info, fullyUpdateBookFiles);
return _collectionModel.GetBookFromBookInfo(info);
}

private Book.Book GetUpdatedBookObjectFromBookInfo(BookInfo info)
{
return _collectionModel.GetBookFromBookInfo(info, true);
return _collectionModel.GetBookFromBookInfo(info);
}
}
}
7 changes: 3 additions & 4 deletions src/BloomTests/Book/BookStarterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void Setup()

_starter = new BookStarter(
_fileLocator,
(dir, fullyUpdateBookFiles) =>
(dir) =>
new BookStorage(dir, _fileLocator, new BookRenamedEvent(), collectionSettings),
_defaultCollectionSettings
);
Expand Down Expand Up @@ -233,8 +233,7 @@ private BookServer CreateBookServer()
new BookRefreshEvent()
);
},
(path, fullyUpdateBookFiles) =>
new BookStorage(path, _fileLocator, null, collectionSettings),
(path) => new BookStorage(path, _fileLocator, null, collectionSettings),
() => _starter,
null
);
Expand Down Expand Up @@ -697,7 +696,7 @@ public void CreateBookOnDiskFromTemplate_HasEnglishTextArea_VernacularTextAreaAd
1
);
}

[Test]
public void CreateBookOnDiskFromTemplate_ConflictingCss_UsesLegacy()
{
Expand Down
4 changes: 2 additions & 2 deletions src/BloomTests/Book/BookTestsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ public BookServer CreateBookServer()
);
var starter = new BookStarter(
fileLocator,
(dir, fullyUpdateBookFiles) =>
(dir) =>
new BookStorage(dir, fileLocator, new BookRenamedEvent(), _collectionSettings),
_collectionSettings
);
Expand All @@ -444,7 +444,7 @@ public BookServer CreateBookServer()
);
},
// storage factory
(info, fullyUpdateBookFiles) =>
(info) =>
{
var storage = new BookStorage(
info,
Expand Down
68 changes: 68 additions & 0 deletions src/BloomTests/CLI/CreateArtifactsCommandTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Bloom.Book;
using Bloom.CLI;
using Bloom.Collection;
using BloomTemp;
using NUnit.Framework;

namespace BloomTests.CLI
Expand Down Expand Up @@ -36,6 +40,15 @@ public void CreateArtifactsExitCode_GetErrorsFromExitCode_BookHtmlNotFound_Retur
CollectionAssert.AreEquivalent(new string[] { "BookHtmlNotFound" }, errors);
}

[Test]
public void CreateArtifactsExitCode_GetErrorsFromExitCode_LegacyBookCannotHarvest_Returns1Error()
{
int exitCode = 8;
var errors = CreateArtifactsCommand.GetErrorsFromExitCode(exitCode);

CollectionAssert.AreEquivalent(new string[] { "LegacyBookCannotHarvest" }, errors);
}

[Test]
public void CreateArtifactsExitCode_GetErrorsFromExitCode_EpubError_Returns1Error()
{
Expand Down Expand Up @@ -82,5 +95,60 @@ public void CreateArtifactsExitCode_GetErrorsFromExitCode_BigNumber_AddsUnknown(

Assert.That(errors.Contains("Unknown"), Is.True);
}

[Test]
public void CreateArtifacts_LegacyBookWithInvalidXmatter_ReportsLegacyBookCannotHarvest()
{
using (
var testFolder = new TemporaryFolder(
"CreateArtifacts_LegacyBookWithInvalidXmatter_ReportsLegacyBookCannotHarvest"
)
)
{
var collectionFolderPath = testFolder.Combine("collection");

var bookFolderPath = Path.Combine(collectionFolderPath, "book");
System.IO.Directory.CreateDirectory(bookFolderPath);
var collectionFilePath = Path.Combine(
collectionFolderPath,
"collection.bloomCollection"
);
var settings = new CollectionSettings(collectionFilePath);
settings.XMatterPackName = "ABC-Reader";
settings.Save();
var metaData = new BookMetaData();
metaData.WriteToFolder(bookFolderPath);
var bookPath = System.IO.Path.Combine(bookFolderPath, "book.htm");
System.IO.File.WriteAllText(
bookPath,
@"<html>
<body>
<div class='bloom-page'>
<div class='marginBox'>
<div class='bloom-translationGroup normal-style'>
<div class='bloom-editable normal-style bloom-content1 bloom-contentNational1 bloom-visibility-code-on' lang='en'>
</div>
</div>
</div>
</div>
</body>
</html>"
);
System.IO.File.WriteAllText(
System.IO.Path.Combine(bookFolderPath, "book.xmatter"),
"invalid"
);
var result = CreateArtifactsCommand.HandleInternal(
new CreateArtifactsParameters()
{
BookPath = bookFolderPath,
CollectionPath = collectionFilePath,
BloomPubOutputPath = Path.Combine(testFolder.FolderPath, "output")
}
);

Assert.That(result, Is.EqualTo(CreateArtifactsExitCode.LegacyBookCannotHarvest));
}
}
}
}
Loading