diff --git a/c-sharp/JsonUtils/ProjectMetadataConverter.cs b/c-sharp/JsonUtils/ProjectMetadataConverter.cs index 3bebb2d518..376dcc136c 100644 --- a/c-sharp/JsonUtils/ProjectMetadataConverter.cs +++ b/c-sharp/JsonUtils/ProjectMetadataConverter.cs @@ -57,5 +57,21 @@ public static string ToJsonString(ProjectMetadata projectMetadata) [PROJECT_TYPE] = projectMetadata.ProjectType }.ToString(); } + + public static string ToJsonString( + string id, + string name, + string storageType, + string projectType + ) + { + return new JObject + { + [ID] = id, + [NAME] = name, + [STORAGE_TYPE] = storageType, + [PROJECT_TYPE] = projectType + }.ToString(); + } } } diff --git a/c-sharp/Projects/LocalParatextProjects.cs b/c-sharp/Projects/LocalParatextProjects.cs index ab4cf5e9c6..508fad40ac 100644 --- a/c-sharp/Projects/LocalParatextProjects.cs +++ b/c-sharp/Projects/LocalParatextProjects.cs @@ -17,7 +17,9 @@ internal class LocalParatextProjects protected const string PROJECT_METADATA_FILE = "meta.json"; // Inside of the project subdirectory, this is the subdirectory for Paratext projects + // A subdirectory for extensions is also located here protected const string PARATEXT_DATA_SUBDIRECTORY = "paratext"; + protected const string EXTENSIONS_SUBDIRECTORY = "extensions"; protected readonly ConcurrentDictionary _projectDetailsMap = new(); @@ -41,7 +43,16 @@ public virtual void Initialize() CreateDirectory(ProjectRootFolder); - foreach (var projectDetails in LoadAllProjectDetails()) + IEnumerable allProjectDetails = LoadAllProjectDetails(); + + if (!allProjectDetails.Any()) + { + SetUpSampleProject(); + + allProjectDetails = LoadAllProjectDetails(); + } + + foreach (ProjectDetails projectDetails in allProjectDetails) { if (projectDetails.Metadata.ProjectStorageType != ProjectStorageType.ParatextFolders) continue; @@ -208,5 +219,37 @@ out string errorMessage return metadata; } + private void SetUpSampleProject() + { + string projectName = "WEB"; + string projectId = "32664dc3288a28df2e2bb75ded887fc8f17a15fb"; + string projectFolderName = projectName + "_" + projectId; + string projectFolder = Path.Join(ProjectRootFolder, projectFolderName); + ProjectMetadata metadata = + new(projectId, projectName, "paratextFolders", "ParatextStandard"); + string metadataString = ProjectMetadataConverter.ToJsonString( + metadata.ID, + metadata.Name, + metadata.ProjectStorageType, + metadata.ProjectType + ); + + CreateDirectory(Path.Join(projectFolder, PROJECT_SUBDIRECTORY, EXTENSIONS_SUBDIRECTORY)); + CreateDirectory(Path.Join(projectFolder, PROJECT_SUBDIRECTORY, PARATEXT_DATA_SUBDIRECTORY)); + + File.WriteAllText(Path.Join(projectFolder, PROJECT_METADATA_FILE), metadataString); + + foreach (string filePath in Directory.GetFiles("assets/" + projectName, "*.*")) + { + File.Copy( + filePath, + filePath.Replace( + "assets/" + projectName, + Path.Join(projectFolder, PROJECT_SUBDIRECTORY, PARATEXT_DATA_SUBDIRECTORY) + ) + ); + } + } + #endregion } diff --git a/src/extension-host/services/project-lookup.service-host.ts b/src/extension-host/services/project-lookup.service-host.ts index 02afcb3ae8..e4ddbce390 100644 --- a/src/extension-host/services/project-lookup.service-host.ts +++ b/src/extension-host/services/project-lookup.service-host.ts @@ -9,6 +9,7 @@ import logger from '@shared/services/logger.service'; import networkObjectService from '@shared/services/network-object.service'; import * as nodeFS from '@node/services/node-file-system.service'; import { deserialize } from '@shared/utils/papi-util'; +import { wait } from '@shared/utils/util'; /** This points to the directory where all of the project subdirectories live */ const PROJECTS_ROOT_URI = joinUriPaths('file://', os.homedir(), '.platform.bible', 'projects'); @@ -17,8 +18,15 @@ const METADATA_FILE = 'meta.json'; /** Get URIs to all projects stored locally on the file system */ async function getProjectUris(): Promise { // Get all the directories in the projects root - const entries = await nodeFS.readDir(PROJECTS_ROOT_URI); - + let entries = await nodeFS.readDir(PROJECTS_ROOT_URI); + if (entries.directory.length === 0) { + // TODO: This is a temporary solution that waits for a project directory when none are found. + // Ideally we would want to run `reloadMetadata()` whenever + // a project is added to or removed from the projects directory. + // https://github.com/paranext/paranext-core/issues/691 + await wait(5000); + entries = await nodeFS.readDir(PROJECTS_ROOT_URI); + } return entries.directory; } diff --git a/src/main/main.ts b/src/main/main.ts index 1d04079adf..6f1b02c6d9 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -23,10 +23,9 @@ import { wait } from '@shared/utils/util'; import { CommandNames } from 'papi-shared-types'; import { SerializedRequestType, serialize } from '@shared/utils/papi-util'; import networkObjectStatusService from '@shared/services/network-object-status.service'; +import { get } from '@shared/services/project-data-provider.service'; +import { VerseRef } from '@sillsdev/scripture'; import { startNetworkObjectStatusService } from './services/network-object-status.service-host'; -// Used with the commented out code at the bottom of this file to test the ParatextProjectDataProvider -// import { get } from '@shared/services/project-data-provider.service'; -// import { VerseRef } from '@sillsdev/scripture'; const PROCESS_CLOSE_TIME_OUT = 2000; @@ -331,20 +330,9 @@ async function main() { // #endregion // #region Test a .NET data provider - // TODO: Uncomment this or similar sample code once https://github.com/paranext/paranext-core/issues/440 is resolved - // In the meantime, if you want to try this, copy an existing project into - // /.platform.bible/_/project/paratext - // For example: "~/.platform.bible/projects/TPKJ_b4c501ad2538989d6fb723518e92408406e232d3/project/paratext" - // Then create a file named "meta.json" in the "_" directory with this JSON: - // { - // "id": "REPLACE_THIS_WITH_PROJECT_ID_FROM_SETTINGS_XML", - // "name": "REPLACE_THIS_WITH_PROJECT_SHORT_NAME", - // "storageType": "paratextFolders", - // "projectType": "ParatextStandard" - // } - /* setTimeout(async () => { - const paratextPdp = await get<'ParatextStandard'>('ParatextStandard', + const paratextPdp = await get<'ParatextStandard'>( + 'ParatextStandard', '32664dc3288a28df2e2bb75ded887fc8f17a15fb', ); const verse = await paratextPdp.getChapterUSX(new VerseRef('JHN', '1', '1')); @@ -357,7 +345,6 @@ async function main() { 'This is the data from extension foo', ); }, 10000); - */ // #endregion } diff --git a/src/renderer/components/run-basic-checks-dialog/run-basic-checks-tab.component.tsx b/src/renderer/components/run-basic-checks-dialog/run-basic-checks-tab.component.tsx index a374f350c9..295edf062e 100644 --- a/src/renderer/components/run-basic-checks-dialog/run-basic-checks-tab.component.tsx +++ b/src/renderer/components/run-basic-checks-dialog/run-basic-checks-tab.component.tsx @@ -137,12 +137,7 @@ export const loadRunBasicChecksTab = (savedTabInfo: SavedTabInfo): TabInfo => { content: ( /.platform.bible/_/project/paratext - // For example: "~/.platform.bible/projects/TPKJ_b4c501ad2538989d6fb723518e92408406e232d3/project/paratext" - // Then create a file named "meta.json" in the "_" directory with this JSON: - currentProjectId="INSERT YOUR PROJECT ID HERE" + currentProjectId="32664dc3288a28df2e2bb75ded887fc8f17a15fb" currentScriptureReference={settingsService.get('platform.verseRef')} /> ),