diff --git a/.github/workflows/CI-build-test.yml b/.github/workflows/CI-build-test.yml index 6d56cbb2..33be8a70 100644 --- a/.github/workflows/CI-build-test.yml +++ b/.github/workflows/CI-build-test.yml @@ -46,7 +46,7 @@ jobs: - name: Copy config run: | cp config.js.ci config.js - touch vision-taxa.txt + touch vision-taxonomy.csv - run: npm install diff --git a/config.docker.js b/config.docker.js index 0d2b46ee..24c4342a 100644 --- a/config.docker.js +++ b/config.docker.js @@ -20,7 +20,7 @@ const { INAT_AWS_OPENDATA_DOMAIN, INAT_AWS_OPENDATA_REGION, INAT_AWS_OPENDATA_ACL, - INAT_TAXA_FILE_PATH, + INAT_TAXONOMY_PATH, INAT_SEEK_EXCEPTION_LIST_ID, INAT_NLS_URL } = process.env; @@ -51,11 +51,12 @@ module.exports = { imageProcesing: { tensorappURL: INAT_VISION_URL || "http://localhost:6006", uploadsDir: "/home/inaturalist/api/public/uploads", - taxaFilePath: INAT_TAXA_FILE_PATH || "", + taxonomyPath: INAT_TAXONOMY_PATH || "", geomodel: true, combinedThreshold: 0.001, frequencyBackend: "redis", - inatnlsURL: INAT_NLS_URL || "" + inatnlsURL: INAT_NLS_URL || "", + delegateCommonAncestor: true }, redis: { host: INAT_REDIS_HOST || "127.0.0.1", diff --git a/config.js.ci b/config.js.ci index c21dbb6d..d62ed400 100644 --- a/config.js.ci +++ b/config.js.ci @@ -14,9 +14,10 @@ module.exports = { staticImagePrefix: "http://localhost:3000/attachments/", userImagePrefix: "/attachments/users/icons/", imageProcesing: { - taxaFilePath: "/home/travis/build/inaturalist/iNaturalistAPI/vision-taxa.txt", + taxonomyPath: "/home/travis/build/inaturalist/iNaturalistAPI/vision-taxonomy.csv", uploadsDir: "/tmp/", - tensorappURL: "http://localhost:6006" + tensorappURL: "http://localhost:6006", + delegateCommonAncestor: true }, tileSize: 512, debug: true, diff --git a/lib/controllers/v1/computervision_controller.js b/lib/controllers/v1/computervision_controller.js index 29e5cd2f..81e71bde 100644 --- a/lib/controllers/v1/computervision_controller.js +++ b/lib/controllers/v1/computervision_controller.js @@ -269,7 +269,11 @@ const ComputervisionController = class ComputervisionController { }; const taxonOpts = { modifier: prepareTaxon, - source: { excludes: ["photos", "place_ids"] } + source: { + excludes: [ + "photos", "place_ids", "listed_taxa.user_id", "listed_taxa.occurrence_status_level" + ] + } }; // if there were taxa added to the counts to replace inactive taxa, @@ -317,6 +321,7 @@ const ComputervisionController = class ComputervisionController { // remove attributes of common_ancestor that should not be in the response if ( response.common_ancestor ) { + await TaxaController.assignPlaces( [response.common_ancestor.taxon] ); response.common_ancestor.score = response.common_ancestor.combined_score; response.common_ancestor = _.omit( response.common_ancestor, [ "combined_score", diff --git a/test/integration/v2/computervision.js b/test/integration/v2/computervision.js index ed9e578f..963b6dc5 100644 --- a/test/integration/v2/computervision.js +++ b/test/integration/v2/computervision.js @@ -17,19 +17,21 @@ describe( "Computervision", ( ) => { ); const url = `/v2/computervision/score_observation/${fixtureObs.uuid}`; beforeEach( ( ) => { - const fakeVisionResults = [{ - id: 1, - combined_score: 0.9, - geo_score: 0.9, - geo_threshold: 1.0, - vision_score: 0.9 - }, { - id: 2, - combined_score: 0.1, - geo_score: 0.1, - geo_threshold: 0.5, - vision_score: 0.1 - }]; + const fakeVisionResults = { + results: [{ + id: 1, + combined_score: 0.9, + geo_score: 0.9, + geo_threshold: 1.0, + vision_score: 0.9 + }, { + id: 2, + combined_score: 0.1, + geo_score: 0.1, + geo_threshold: 0.5, + vision_score: 0.1 + }] + }; nock( config.imageProcesing.tensorappURL ) .post( "/" ) .reply( 200, fakeVisionResults ); @@ -95,19 +97,21 @@ describe( "Computervision", ( ) => { { algorithm: "HS512" } ); beforeEach( ( ) => { - const fakeVisionResults = [{ - id: 1, - combined_score: 0.9, - geo_score: 0.9, - geo_threshold: 1.0, - vision_score: 0.9 - }, { - id: 2, - combined_score: 0.1, - geo_score: 0.1, - geo_threshold: 0.5, - vision_score: 0.1 - }]; + const fakeVisionResults = { + results: [{ + id: 1, + combined_score: 0.9, + geo_score: 0.9, + geo_threshold: 1.0, + vision_score: 0.9 + }, { + id: 2, + combined_score: 0.1, + geo_score: 0.1, + geo_threshold: 0.5, + vision_score: 0.1 + }] + }; nock( config.imageProcesing.tensorappURL ) .post( "/" ) .reply( 200, fakeVisionResults ); diff --git a/test/integration/v2/taxa.js b/test/integration/v2/taxa.js index c0e36809..7069fee0 100644 --- a/test/integration/v2/taxa.js +++ b/test/integration/v2/taxa.js @@ -134,7 +134,15 @@ describe( "Taxa", ( ) => { const sandbox = sinon.createSandbox( ); afterEach( ( ) => sandbox.restore( ) ); it( "accepts an image and returns results", function ( done ) { - const fakeVisionResults = { 1: 0.01 }; + const fakeVisionResults = { + results: [{ + id: 1, + combined_score: 0.9, + geo_score: 0.9, + geo_threshold: 1.0, + vision_score: 0.9 + }] + }; nock( config.imageProcesing.tensorappURL ) .post( "/" ) .reply( 200, fakeVisionResults ); @@ -156,9 +164,7 @@ describe( "Taxa", ( ) => { // Ensure ComputervisionController.scoreImage gets called and not scoreImageURL expect( scoreImageSpy ).to.have.been.calledOnce; // Ensure response includes the taxon from vision - expect( res.body.results[0].taxon.id ).to.eq( - parseInt( _.keys( fakeVisionResults )[0], 10 ) - ); + expect( res.body.results[0].taxon.id ).to.eq( fakeVisionResults.results[0].id ); // Ensure fields is working on the results expect( res.body.results[0].taxon.name ).not.to.be.undefined; expect( res.body.results[0].taxon.rank ).to.be.undefined;