11import { arrayIsNotEmpty , clone , isSet , loadJsonResource } from "../lib/Common.js" ;
2- import { firstImageOf , postHtmlOf , postImageOf , postInfoOf , postLinkOf , postTextOf } from "../domain/post.js" ;
2+ import {
3+ firstImageOf ,
4+ postAuthorOf ,
5+ postHtmlOf ,
6+ postImageOf ,
7+ postInfoOf ,
8+ postLinkOf ,
9+ postTextOf
10+ } from "../domain/post.js" ;
311import TinyURL from "tinyurl" ;
412
513const PLANTNET_MINIMAL_PERCENT = 20 ;
@@ -39,7 +47,7 @@ export default class Plantnet {
3947 return this . isAvailable ;
4048 }
4149
42- process ( config ) {
50+ async process ( config ) {
4351 const plugin = this ;
4452 let { pluginTags, pluginMoreTags, doSimulate, simulateIdentifyCase, context} = config ;
4553 if ( config . pluginName === undefined ) {
@@ -53,36 +61,37 @@ export default class Plantnet {
5361 }
5462 // if at least one want to simulate then simulate
5563 const doSimulateIdentify = plugin . plantnetSimulate || isSet ( simulateIdentifyCase ) ;
56- return new Promise ( ( resolve , reject ) => {
57- plugin . searchNextCandidate ( config )
58- . then ( candidate => {
59- const candidatePhoto = firstImageOf ( candidate ) ;
60- if ( ! candidatePhoto ) {
61- plugin . logger . info ( "no candidate image" , context ) ;
62- throw { "message" : `aucune image pour Pl@ntNet dans ${ postLinkOf ( candidate ) } ` , "status" : 202 } ;
63- }
64- plugin . logger . debug ( `post Candidate : ${ postLinkOf ( candidate ) } \n` +
65- `\t${ postInfoOf ( candidate ) } \n` +
66- `\t${ postImageOf ( candidatePhoto ) } ` , context ) ;
64+ try {
65+ const candidate = await plugin . searchNextCandidate ( config ) ;
66+ const candidatePhoto = firstImageOf ( candidate ) ;
67+ if ( ! candidatePhoto ) {
68+ plugin . logger . info ( "no candidate image" , context ) ;
69+ return Promise . reject ( {
70+ "message" : `aucune image pour Pl@ntNet dans ${ postLinkOf ( candidate ) } ` ,
71+ "status" : 202
72+ } ) ;
73+ }
74+ plugin . logger . debug ( `post Candidate : ${ postLinkOf ( candidate ) } \n` +
75+ `\t${ postInfoOf ( candidate ) } \n` +
76+ `\t${ postImageOf ( candidatePhoto ) } ` , context ) ;
6777
68- const candidateImageFullsize = candidatePhoto ?. fullsize ;
78+ const candidateImageFullsize = candidatePhoto ?. fullsize ;
6979
70- const identifyOptions = {
71- "image" : candidateImageFullsize ,
72- doSimulate,
73- doSimulateIdentify,
74- simulateIdentifyCase,
75- candidate,
76- "tags" : pluginTags ,
77- context
78- } ;
79- plugin . logger . debug ( `identifyOptions : ${ identifyOptions } ` , context ) ;
80- plugin . plantnetIdentify ( identifyOptions )
81- . then ( resolve )
82- . catch ( reject )
83- } )
84- . catch ( reject ) ;
85- } ) ;
80+ const identifyOptions = {
81+ "image" : candidateImageFullsize ,
82+ doSimulate,
83+ doSimulateIdentify,
84+ simulateIdentifyCase,
85+ candidate,
86+ "tags" : pluginTags ,
87+ context
88+ } ;
89+ plugin . logger . debug ( `identifyOptions : ${ identifyOptions } ` , context ) ;
90+ const result = await plugin . plantnetIdentify ( identifyOptions ) ;
91+ return Promise . resolve ( result ) ;
92+ } catch ( err ) {
93+ return Promise . reject ( err ) ;
94+ }
8695 }
8796
8897 /**
@@ -100,21 +109,26 @@ export default class Plantnet {
100109 */
101110 searchNextCandidate ( config , bookmark = 0 ) {
102111 const plugin = this ;
103- const { pluginName, context} = config ;
112+ const { pluginName, context, doSimulateSearch } = config ;
104113 return new Promise ( ( resolve , reject ) => {
114+ if ( doSimulateSearch ) {
115+ plugin . blueskyService . login ( ) . then ( ( ) => {
116+ return resolve ( loadJsonResource ( "src/data/blueskyPostFakeFlower.json" ) ) ;
117+ } )
118+ }
105119 let searchQuery = plugin . questions [ bookmark ] ;
106120 if ( config . searchExtra ) {
107121 searchQuery += " " + config . searchExtra ;
108122 }
109123 const hasImages = true ;
110124 const hasNoReply = true ;
125+ const isNotMuted = true ;
111126 const maxHoursOld = 24 ; // now-24h ... now
112- plugin . blueskyService . searchPosts ( { searchQuery, hasImages, hasNoReply, maxHoursOld} )
127+ plugin . blueskyService . searchPosts ( { searchQuery, hasImages, hasNoReply, isNotMuted , maxHoursOld} )
113128 . then ( candidatePosts => {
114129 plugin . logger . info ( `${ candidatePosts . length } candidate(s)` , context ) ;
115130 if ( arrayIsNotEmpty ( candidatePosts ) ) {
116- resolve ( candidatePosts [ 0 ] ) ;
117- return ;
131+ return resolve ( candidatePosts [ 0 ] ) ;
118132 }
119133 if ( bookmark + 1 < plugin . questions . length ) {
120134 plugin . searchNextCandidate ( config , bookmark + 1 )
@@ -129,35 +143,34 @@ export default class Plantnet {
129143 } ) ;
130144 }
131145
132- plantnetIdentify ( options ) {
146+ async plantnetIdentify ( options ) {
133147 const plugin = this ;
134148 const { image, doSimulate, doSimulateIdentify, simulateIdentifyCase, candidate, context} = options ;
135-
136- return new Promise ( ( resolve , reject ) => {
137- plugin . plantnetService . identify ( { "imageUrl" : image , doSimulateIdentify, simulateIdentifyCase} )
138- . then ( plantResult => {
139- plugin . logger . debug ( `plantnetResult : ${ JSON . stringify ( plantResult ) } ` , context ) ;
140- const firstScoredResult = plugin . plantnetService . hasScoredResult ( plantResult , PLANTNET_MINIMAL_RATIO ) ;
141- if ( ! firstScoredResult ) {
142- plugin . resolveWithoutScoredResult ( options ) . then ( resolve ) . catch ( reject ) ;
143- return ;
144- }
145- plugin . replyScoredResultWithImage ( options , firstScoredResult ) . then ( resolve ) . catch ( reject ) ;
146- } )
147- . catch ( err => {
148- plugin . logError ( "plantnetService.identify" , err , { ...context , image, doSimulate} ) ;
149- if ( err ?. status === 404 ) {
150- plugin . resolveWithNoIdentificationResult ( options ) . then ( resolve ) ;
151- return
152- }
153- reject ( {
154- "message" : "impossible d'identifier l'image" ,
155- "html" : `<b>Post</b>: <div class="bg-warning">${ postHtmlOf ( candidate ) } </div>` +
156- `<b>Erreur</b>: impossible d'identifier l'image` ,
157- "status" : 500
158- } ) ;
159- } ) ;
160- } ) ;
149+ let plantResult ;
150+ try {
151+ plantResult = await plugin . plantnetService . identify ( {
152+ "imageUrl" : image ,
153+ doSimulateIdentify,
154+ simulateIdentifyCase
155+ } ) ;
156+ } catch ( err ) {
157+ plugin . logError ( "plantnetService.identify" , err , { ...context , image, doSimulate} ) ;
158+ if ( err ?. status === 404 ) {
159+ return await plugin . resolveWithNoIdentificationResult ( options ) ;
160+ }
161+ return Promise . reject ( {
162+ "text" : "impossible d'identifier l'image" ,
163+ "html" : `<b>Post</b>: <div class="bg-warning">${ postHtmlOf ( candidate ) } </div>` +
164+ `<b>Erreur</b>: impossible d'identifier l'image` ,
165+ "status" : 500
166+ } ) ;
167+ }
168+ plugin . logger . debug ( `plantnetResult : ${ JSON . stringify ( plantResult ) } ` , context ) ;
169+ const firstScoredResult = plugin . plantnetService . hasScoredResult ( plantResult , PLANTNET_MINIMAL_RATIO ) ;
170+ if ( ! firstScoredResult ) {
171+ return plugin . resolveWithoutScoredResult ( options ) ;
172+ }
173+ return plugin . replyScoredResultWithImage ( options , firstScoredResult ) ;
161174 }
162175
163176 buildShortUrlWithText ( imageUrl , text ) {
@@ -218,22 +231,24 @@ export default class Plantnet {
218231 } ) ;
219232 }
220233
221- resolveWithNoIdentificationResult ( options ) {
222- const { candidate} = options ;
234+ async resolveWithNoIdentificationResult ( options ) {
235+ const { candidate, context } = options ;
223236 const candidateHtmlOf = postHtmlOf ( candidate ) ;
224237 const candidateTextOf = postTextOf ( candidate ) ;
225- const noIdentificationText = " ne donne aucune identification Pl@ntNet" ;
238+ const noIdentificationText = "L'identification par Pl@ntNet ne donne aucun résultat (auteur masqué)" ;
239+ await this . blueskyService . safeMuteCandidateAuthor ( postAuthorOf ( candidate ) , noIdentificationText , context ) ;
226240 return Promise . resolve ( {
227241 "html" : `<b>Post</b>:<div class="bg-info">${ candidateHtmlOf } </div> ${ noIdentificationText } ` ,
228242 "text" : `Post:\n\t${ candidateTextOf } \n\t${ noIdentificationText } `
229243 } ) ;
230244 }
231245
232- resolveWithoutScoredResult ( options ) {
233- const { candidate} = options ;
246+ async resolveWithoutScoredResult ( options ) {
247+ const { candidate, context } = options ;
234248 const candidateHtmlOf = postHtmlOf ( candidate ) ;
235249 const candidateTextOf = postTextOf ( candidate ) ;
236- const noIdentificationGoodScoreText = `L'identification par Pl@ntNet n'a pas donné de résultat assez concluant 😩 (score<${ PLANTNET_MINIMAL_PERCENT } %)` ;
250+ const noIdentificationGoodScoreText = `L'identification par Pl@ntNet n'a pas donné de résultat assez concluant 😩 (score<${ PLANTNET_MINIMAL_PERCENT } %)(auteur masqué)` ;
251+ await this . blueskyService . safeMuteCandidateAuthor ( postAuthorOf ( candidate ) , noIdentificationGoodScoreText , context ) ;
237252 return Promise . resolve ( {
238253 "html" : `<b>Post</b>:<div class="bg-info">${ candidateHtmlOf } </div> ${ noIdentificationGoodScoreText } ` ,
239254 "text" : `Post:\n\t${ candidateTextOf } \n\t${ noIdentificationGoodScoreText } `
0 commit comments