4646import org .openhab .core .addon .marketplace .internal .community .model .DiscourseCategoryResponseDTO .DiscourseTopicItem ;
4747import org .openhab .core .addon .marketplace .internal .community .model .DiscourseCategoryResponseDTO .DiscourseUser ;
4848import org .openhab .core .addon .marketplace .internal .community .model .DiscourseTopicResponseDTO ;
49- import org .openhab .core .addon .marketplace .internal .community .model .DiscourseTopicResponseDTO .DiscoursePostLink ;
5049import org .openhab .core .common .VersionRange ;
5150import org .openhab .core .config .core .ConfigParser ;
5251import org .openhab .core .config .core .ConfigurableService ;
@@ -97,6 +96,8 @@ public class CommunityMarketplaceAddonService extends AbstractRemoteAddonService
9796 private static final Pattern CODE_MARKUP_PATTERN = Pattern .compile (
9897 "<pre(?: data-code-wrap=\" [-a-zA-Z]+\" )?><code class=\" lang-(?<lang>[-a-zA-Z]+)\" >(?<content>.*?)</code></pre>\\ n?" ,
9998 Pattern .DOTALL );
99+ private static final Pattern LAST_RESOURCE_LINK_PATTERN = Pattern .compile (
100+ ".*href=\" (?<url>[^\" ]+\\ .(?<extension>jar|kar|json|yaml))\" " , Pattern .DOTALL | Pattern .CASE_INSENSITIVE );
100101
101102 private static final Integer BUNDLES_CATEGORY = 73 ;
102103 private static final Integer RULETEMPLATES_CATEGORY = 74 ;
@@ -407,46 +408,46 @@ private Addon convertTopicToAddon(DiscourseTopicResponseDTO topic) {
407408 String detailedDescription = topic .postStream .posts [0 ].cooked ;
408409 String id = null ;
409410
410- // try to extract contents or links
411- if (topic .postStream .posts [0 ].linkCounts != null ) {
412- URI uri ;
413- String path ;
414- for (DiscoursePostLink postLink : topic .postStream .posts [0 ].linkCounts ) {
415- try {
416- uri = processResourceURL (postLink .url );
417- path = uri .getPath ();
418- if (path == null ) {
419- continue ;
411+ Matcher matcher = LAST_RESOURCE_LINK_PATTERN .matcher (detailedDescription );
412+ if (matcher .find ()) {
413+ try {
414+ URI uri = processResourceURL (matcher .group ("url" ));
415+ String path = uri .getPath ();
416+ if (path != null ) {
417+ switch (matcher .group ("extension" ).toLowerCase (Locale .ROOT )) {
418+ case "jar" :
419+ properties .put (JAR_DOWNLOAD_URL_PROPERTY , uri .toString ());
420+ id = determineIdFromUrl (path );
421+ break ;
422+ case "kar" :
423+ properties .put (KAR_DOWNLOAD_URL_PROPERTY , uri .toString ());
424+ id = determineIdFromUrl (path );
425+ break ;
426+ case "json" :
427+ properties .put (JSON_DOWNLOAD_URL_PROPERTY , uri .toString ());
428+ break ;
429+ case "yaml" :
430+ properties .put (YAML_DOWNLOAD_URL_PROPERTY , uri .toString ());
431+ break ;
420432 }
421- } catch (IllegalArgumentException e ) {
422- continue ;
423- }
424- path = path .toLowerCase (Locale .ROOT );
425- if (path .endsWith (".jar" )) {
426- properties .put (JAR_DOWNLOAD_URL_PROPERTY , uri .toString ());
427- id = determineIdFromUrl (postLink .url );
428- }
429- if (path .endsWith (".kar" )) {
430- properties .put (KAR_DOWNLOAD_URL_PROPERTY , uri .toString ());
431- id = determineIdFromUrl (postLink .url );
432- }
433- if (path .endsWith (".json" )) {
434- properties .put (JSON_DOWNLOAD_URL_PROPERTY , uri .toString ());
435- }
436- if (path .endsWith (".yaml" )) {
437- properties .put (YAML_DOWNLOAD_URL_PROPERTY , uri .toString ());
433+ } else {
434+ logger .debug (
435+ "Failed to extract path from resource URL for marketplace add-on '{}'. This should be impossible" ,
436+ topic .title );
438437 }
438+ } catch (IllegalArgumentException e ) {
439+ logger .debug ("Add-on '{}' ({}) has an invalid resource URL '{}': {}" , topic .title , topic .id ,
440+ matcher .group ("url" ), e .getMessage ());
439441 }
440442 }
441443
442444 if (id == null ) {
443445 id = topic .id .toString (); // this is a fallback if we couldn't find a better id
444446 }
445447
446- Matcher codeMarkup = CODE_MARKUP_PATTERN .matcher (detailedDescription );
447- if (codeMarkup .find ()) {
448- properties .put (codeMarkup .group ("lang" ) + CODE_CONTENT_SUFFIX ,
449- unescapeEntities (codeMarkup .group ("content" )));
448+ matcher = CODE_MARKUP_PATTERN .matcher (detailedDescription );
449+ if (matcher .find ()) {
450+ properties .put (matcher .group ("lang" ) + CODE_CONTENT_SUFFIX , unescapeEntities (matcher .group ("content" )));
450451 }
451452
452453 // try to use a handler to determine if the add-on is installed
@@ -455,7 +456,7 @@ private Addon convertTopicToAddon(DiscourseTopicResponseDTO topic) {
455456
456457 String title = topic .title ;
457458 boolean compatible = true ;
458- Matcher matcher = VersionRange .RANGE_PATTERN .matcher (title );
459+ matcher = VersionRange .RANGE_PATTERN .matcher (title );
459460 if (matcher .find ()) {
460461 compatible = VersionRange .valueOf (matcher .group ().trim ()).includes (coreVersion );
461462 title = matcher .replaceFirst ("" ).trim ();
0 commit comments