diff --git a/FHEM/98_Installer.pm b/FHEM/98_Installer.pm
index 99af43599..ffbd8c462 100644
--- a/FHEM/98_Installer.pm
+++ b/FHEM/98_Installer.pm
@@ -230,7 +230,11 @@ sub Get($$@) {
my ( $cmd, @args ) = @aa;
- if ( lc($cmd) eq 'showmoduleinfo' ) {
+ if ( lc($cmd) eq 'search' ) {
+ my $ret = CreateSearchList( $hash, $cmd, $args[0] );
+ return $ret;
+ }
+ elsif ( lc($cmd) eq 'showmoduleinfo' ) {
return "usage: $cmd MODULE" if ( @args != 1 );
my $ret = CreateMetadataList( $hash, $cmd, $args[0] );
@@ -242,17 +246,38 @@ sub Get($$@) {
my $ret = CreateRawMetaJson( $hash, $cmd, $args[0] );
return $ret;
}
- else {
- my $fhemModules;
+ elsif ( lc($cmd) eq 'zzgetmaintainer.json' ) {
+ return "usage: $cmd MAINTAINER" if ( @args != 1 );
+ my $ret = CreateRawMaintainerJson( $hash, $cmd, $args[0] );
+ return $ret;
+ }
+ else {
+ my @fhemModules;
foreach ( sort { "\L$a" cmp "\L$b" } keys %modules ) {
next if ( $_ eq 'Global' );
- $fhemModules .= ',' if ($fhemModules);
- $fhemModules .= $_;
+ push @fhemModules, $_;
+ }
+
+ my @fhemMaintainers;
+ foreach ( keys %FHEM::Meta::maintainerModules ) {
+ push @fhemMaintainers, $_;
+ }
+ foreach ( keys %FHEM::Meta::maintainerPackages ) {
+ push @fhemMaintainers, $_;
+ }
+ foreach ( keys %FHEM::Meta::maintainerFile ) {
+ push @fhemMaintainers, $_;
}
my $list =
- "zzGetMETA.json:FHEM,$fhemModules showModuleInfo:FHEM,$fhemModules";
+ 'search'
+ . ' showModuleInfo:FHEM,'
+ . join( ',', @fhemModules )
+ . ' zzGetMaintainer.json:'
+ . join( ',', sort { "\L$a" cmp "\L$b" } __aUniq(@fhemMaintainers) )
+ . ' zzGetMETA.json:FHEM,'
+ . join( ',', @fhemModules );
return "Unknown argument $cmd, choose one of $list";
}
@@ -342,7 +367,7 @@ sub ProcessUpdateTimer($) {
or ReadingsVal( $name, 'state', 'none' ) eq 'initialized' );
if (
- ToDay() ne (
+ __ToDay() ne (
split(
' ', ReadingsTimestamp( $name, 'outdated', '1970-01-01' )
)
@@ -793,7 +818,7 @@ sub WriteReadings($$) {
: 'check failed'
)
);
- $hash->{helper}{lastSync} = ToDay();
+ $hash->{helper}{lastSync} = __ToDay();
}
readingsBulkUpdateIfChanged( $hash, 'updatesAvailable',
@@ -853,6 +878,269 @@ sub WriteReadings($$) {
&& !defined( $decode_json->{error} ) );
}
+sub CreateSearchList ($$$) {
+ my ( $hash, $getCmd, $search ) = @_;
+ $search = '.+' unless ($search);
+
+ # disable automatic links to FHEM devices
+ delete $FW_webArgs{addLinks};
+
+ my @ret;
+ my $html = defined( $hash->{CL} ) && $hash->{CL}{TYPE} eq "FHEMWEB" ? 1 : 0;
+
+ my $header = '';
+ my $footer = '';
+ if ($html) {
+ $header = '';
+ $footer = '';
+ }
+
+ my $tableOpen = '';
+ my $rowOpen = '';
+ my $rowOpenEven = '';
+ my $rowOpenOdd = '';
+ my $colOpen = '';
+ my $colOpenMinWidth = '';
+ my $txtOpen = '';
+ my $txtClose = '';
+ my $colClose = "\t\t\t";
+ my $rowClose = '';
+ my $tableClose = '';
+ my $colorRed = '';
+ my $colorGreen = '';
+ my $colorClose = '';
+
+ if ($html) {
+ $tableOpen = '
';
+ $rowOpen = '';
+ $rowOpenEven = '
';
+ $rowOpenOdd = '
';
+ $colOpen = '';
+ $colOpenMinWidth = ' | ';
+ $txtOpen = "";
+ $txtClose = "";
+ $colClose = ' | ';
+ $rowClose = '
';
+ $tableClose = '
';
+ $colorRed = '';
+ $colorGreen = '';
+ $colorClose = '';
+ }
+
+ my $space = $html ? ' ' : ' ';
+ my $lb = $html ? '
' : "\n";
+ my $lang = lc(
+ AttrVal(
+ $hash->{NAME}, 'language',
+ AttrVal( 'global', 'language', 'EN' )
+ )
+ );
+
+ my $webname =
+ AttrVal( $hash->{CL}{SNAME}, 'webname', 'fhem' );
+ my $FW_CSRF = (
+ defined( $defs{ $hash->{CL}{SNAME} }{CSRFTOKEN} )
+ ? '&fwcsrf=' . $defs{ $hash->{CL}{SNAME} }{CSRFTOKEN}
+ : ''
+ );
+
+ push @ret, 'Search result: ' . $search . '
';
+ my $found = 0;
+
+ # search for matching device
+ my $foundDevices = 0;
+ my $linecount = 1;
+ foreach my $device ( sort keys %defs ) {
+ next
+ unless ( defined( $defs{$device}{TYPE} )
+ && defined( $modules{ $defs{$device}{TYPE} } ) );
+
+ if ( $device =~ m/^.*$search.*$/i ) {
+ unless ($foundDevices) {
+ push @ret, 'Devices
' . $lb;
+ push @ret, $tableOpen;
+ push @ret,
+ $colOpenMinWidth
+ . $txtOpen
+ . 'Device Name'
+ . $txtClose
+ . $colClose;
+ push @ret,
+ $colOpen . $txtOpen . 'Module Name' . $txtClose . $colClose;
+ }
+ $found++;
+ $foundDevices++;
+
+ my $l = $linecount % 2 == 0 ? $rowOpenEven : $rowOpenOdd;
+
+ FHEM::Meta::Load( $modules{ $defs{$device}{TYPE} } );
+
+ my $linkDev = $device;
+ $linkDev =
+ ''
+ . $device . ''
+ if ($html);
+
+ my $linkMod = $defs{$device}{TYPE};
+ $linkMod =
+ ''
+ . $defs{$device}{TYPE} . ''
+ if ($html);
+
+ $l .= $colOpenMinWidth . $linkDev . $colClose;
+ $l .= $colOpen . $linkMod . $colClose;
+
+ $l .= $rowClose;
+
+ push @ret, $l;
+ $linecount++;
+ }
+ }
+ push @ret, $tableClose if ($foundDevices);
+
+ # search for matching module
+ my $foundModules = 0;
+ $linecount = 1;
+ foreach my $module ( sort keys %modules ) {
+ if ( $module =~ m/^.*$search.*$/i ) {
+ unless ($foundModules) {
+ push @ret, 'Modules
' . $lb;
+ push @ret, $tableOpen;
+ push @ret,
+ $colOpenMinWidth
+ . $txtOpen
+ . 'Module Name'
+ . $txtClose
+ . $colClose;
+ push @ret,
+ $colOpen . $txtOpen . 'Abstract' . $txtClose . $colClose;
+ }
+ $found++;
+ $foundModules++;
+
+ my $l = $linecount % 2 == 0 ? $rowOpenEven : $rowOpenOdd;
+
+ FHEM::Meta::Load($module);
+
+ my $abstract = '';
+ $abstract = $modules{$module}{META}{abstract}
+ if ( defined( $modules{$module}{META} )
+ && defined( $modules{$module}{META}{abstract} ) );
+
+ my $link = $module;
+ $link =
+ ''
+ . $module . ''
+ if ($html);
+
+ $l .= $colOpenMinWidth . $link . $colClose;
+ $l .=
+ $colOpen . ( $abstract eq 'n/a' ? '' : $abstract ) . $colClose;
+
+ $l .= $rowClose;
+
+ push @ret, $l;
+ $linecount++;
+ }
+ }
+ push @ret, $tableClose if ($foundModules);
+
+ # search for matching keyword
+ my $foundKeywords = 0;
+ $linecount = 1;
+ foreach my $keyword (%FHEM::Meta::keywords) {
+ if ( $keyword =~ m/^.*$search.*$/i ) {
+ push @ret, 'Keywords
' unless ($foundKeywords);
+ $found++;
+ $foundKeywords++;
+
+ push @ret, '' . $keyword . '
';
+
+ my @mAttrs = qw(
+ modules
+ packages
+ );
+
+ push @ret, $tableOpen;
+
+ push @ret,
+ $colOpenMinWidth . $txtOpen . 'Name' . $txtClose . $colClose;
+
+ push @ret, $colOpen . $txtOpen . 'Type' . $txtClose . $colClose;
+
+ push @ret, $colOpen . $txtOpen . 'Abstract' . $txtClose . $colClose;
+
+ foreach my $mAttr (@mAttrs) {
+ next
+ unless ( defined( $FHEM::Meta::keywords{$keyword}{$mAttr} )
+ && @{ $FHEM::Meta::keywords{$keyword}{$mAttr} } > 0 );
+
+ foreach my $item ( sort { "\L$a" cmp "\L$b" }
+ @{ $FHEM::Meta::keywords{$keyword}{$mAttr} } )
+ {
+ my $l = $linecount % 2 == 0 ? $rowOpenEven : $rowOpenOdd;
+
+ my $type = $mAttr;
+ $type = 'Module' if ( $mAttr eq 'modules' );
+ $type = 'Perl Package' if ( $mAttr eq 'packages' );
+
+ FHEM::Meta::Load($item);
+
+ my $abstract = '';
+ $abstract = $modules{$item}{META}{abstract}
+ if ( defined( $modules{$item} )
+ && defined( $modules{$item}{META} )
+ && defined( $modules{$item}{META}{abstract} ) );
+
+ my $link = $item;
+ $link =
+ ''
+ . $item . ''
+ if ($html);
+
+ $l .= $colOpenMinWidth . $link . $colClose;
+ $l .= $colOpen . $type . $colClose;
+ $l .=
+ $colOpen
+ . ( $abstract eq 'n/a' ? '' : $abstract )
+ . $colClose;
+
+ $l .= $rowClose;
+
+ push @ret, $l;
+ $linecount++;
+ }
+ }
+
+ push @ret, $tableClose;
+ }
+ }
+
+ return $header . join( "\n", @ret ) . $footer;
+}
+
#TODO
# - show master/slave dependencies
# - show parent/child dependencies
@@ -992,12 +1280,6 @@ sub CreateMetadataList ($$$) {
&& ( !defined( $modMeta->{resources} )
|| !defined( $modMeta->{resources}{x_wiki} ) )
);
- next
- if (
- $mAttr eq 'command_reference'
- && ( !defined( $modMeta->{resources} )
- || !defined( $modMeta->{resources}{x_commandref} ) )
- );
next
if (
$mAttr eq 'community_support'
@@ -1040,6 +1322,14 @@ sub CreateMetadataList ($$$) {
$mAttrName =~ s/_/$space/g;
$mAttrName =~ s/([\w'&]+)/\u\L$1/g;
+ my $webname =
+ AttrVal( $hash->{CL}{SNAME}, 'webname', 'fhem' );
+ my $FW_CSRF = (
+ defined( $defs{ $hash->{CL}{SNAME} }{CSRFTOKEN} )
+ ? '&fwcsrf=' . $defs{ $hash->{CL}{SNAME} }{CSRFTOKEN}
+ : ''
+ );
+
$l .= $colOpenMinWidth . $txtOpen . $mAttrName . $txtClose . $colClose;
# these attributes do not exist under that name in META.json
@@ -1130,14 +1420,10 @@ sub CreateMetadataList ($$$) {
}
elsif ( $mAttr eq 'command_reference' ) {
- my $webname;
-
if ( defined( $hash->{CL} )
&& defined( $hash->{CL}{TYPE} )
&& $hash->{CL}{TYPE} eq 'FHEMWEB' )
{
- $webname =
- AttrVal( $hash->{CL}{SNAME}, 'webname', 'fhem' );
$l .=
'{description} )
- ? ' title="' . $board->{description} . '"'
- : ''
+ ? ' title="'
+ . $board->{description}
+ . '"'
+ : (
+ defined(
+ $modMeta->{resources}{x_support_community}
+ {description}
+ )
+ ? ' title="'
+ . $modMeta->{resources}{x_support_community}
+ {description} . '"'
+ : ''
+ )
)
. '>'
. $title . '';
@@ -1536,6 +1833,29 @@ m/^([^<>\n\r]+?)(?:\s+(\(last release only\)))?(?:\s+(?:<(.*)>))?$/
$counter++;
}
}
+ elsif ( $mAttr eq 'keywords' ) {
+ my $counter = 0;
+ foreach my $keyword ( @{ $modMeta->{$mAttr} } ) {
+ $l .= ', ' if ($counter);
+
+ if ($html) {
+ $l .=
+ ''
+ . $keyword . '';
+ }
+ else {
+ $l .= $keyword;
+ }
+
+ $counter++;
+ }
+ }
else {
$l .= join ', ', @{ $modMeta->{$mAttr} };
}
@@ -1622,10 +1942,10 @@ m/^([^<>\n\r]+?)(?:\s+(\(last release only\)))?(?:\s+(?:<(.*)>))?$/
my $check = __IsInstalledPerl($prereq);
my $installed = '';
if ($check) {
- if ( $check =~ m/^\d+\./ ) {
+ if ( $check ne '1' ) {
my $nverReq =
- $version ne ''
- ? $version
+ $version ne ''
+ ? version->parse($version)->numify
: 0;
my $nverInst = $check;
@@ -1965,6 +2285,33 @@ sub CreateRawMetaJson ($$$) {
return $j->encode( $modules{$modName}{META} );
}
+sub CreateRawMaintainerJson ($$$) {
+ my ( $hash, $getCmd, $maintainer ) = @_;
+ my %ret = ();
+
+ $ret{fhem_modules} = $FHEM::Meta::maintainerModules{$maintainer}
+ if ( defined( $FHEM::Meta::maintainerModules{$maintainer} ) );
+
+ $ret{fhem_packages} = $FHEM::Meta::maintainerPackages{$maintainer}
+ if ( defined( $FHEM::Meta::maintainerPackages{$maintainer} ) );
+
+ $ret{fhem_files} = $FHEM::Meta::maintainerFile{$maintainer}
+ if ( defined( $FHEM::Meta::maintainerFile{$maintainer} ) );
+
+ if ( scalar keys %ret > 0 ) {
+ $ret{fhem_maintainer} = $maintainer;
+ }
+ else {
+ return '{}';
+ }
+
+ my $j = JSON->new;
+ $j->allow_nonref;
+ $j->canonical;
+ $j->pretty;
+ return $j->encode( \%ret );
+}
+
# Checks whether a perl package is installed in the system
sub __IsInstalledPerl($) {
return 0 unless ( __PACKAGE__ eq caller(0) );
@@ -2009,8 +2356,7 @@ sub __IsInstalledPython($) {
return 0;
}
-#### my little helper
-sub ToDay() {
+sub __ToDay() {
my ( $sec, $min, $hour, $mday, $month, $year, $wday, $yday, $isdst ) =
localtime( gettimeofday() );
@@ -2023,6 +2369,11 @@ sub ToDay() {
return $today;
}
+sub __aUniq {
+ my %seen;
+ grep !$seen{$_}++, @_;
+}
+
1;
=pod
@@ -2093,7 +2444,7 @@ sub ToDay() {
"abstract": "Modul zum Update von FHEM, zur Installation von Drittanbieter FHEM Modulen und der Verwaltung von Systemvoraussetzungen"
}
},
- "version": "v0.0.3",
+ "version": "v0.1.0",
"release_status": "testing",
"author": [
"Julian Pawlowski "
diff --git a/FHEM/Meta.pm b/FHEM/Meta.pm
index 1ef8f3605..4edae16e7 100644
--- a/FHEM/Meta.pm
+++ b/FHEM/Meta.pm
@@ -372,6 +372,8 @@ our %moduleUpdates;
our %packageUpdates;
our %fileUpdates;
+our %keywords;
+
# Package internal variables
#
@@ -1476,14 +1478,16 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
# Other modules shall get this added elsewhere for performance reasons
if ( $modMeta->{name} eq __PACKAGE__ ) {
$modMeta->{generated_by} =
- $modMeta->{name} . ' ' . $modMeta->{version} . ', ' . TimeNow();
+ $modMeta->{name} . ' '
+ . version->parse( $modMeta->{version} )->normal . ', '
+ . TimeNow();
}
# If we are not running in loop, this is not time consuming for us here
elsif ( !$runInLoop ) {
$modMeta->{generated_by} =
$packages{Meta}{name} . ' '
- . __PACKAGE__->VERSION() . ', '
+ . version->parse( __PACKAGE__->VERSION() )->normal . ', '
. TimeNow();
}
@@ -1549,16 +1553,16 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
foreach (
split(
- '/', $moduleMaintainers{ $modMeta->{x_file}[4] }[1]
+ '/|,', $moduleMaintainers{ $modMeta->{x_file}[4] }[1]
)
)
{
- push @{ $modMeta->{author} }, $_;
+ push @{ $modMeta->{author} }, "$_ <>";
}
# last update was not by one of the named authors
if ( defined( $modMeta->{x_vcs} ) ) {
- my $lastEditor = $modMeta->{x_vcs}[15];
+ my $lastEditor = $modMeta->{x_vcs}[15] . ' <>';
push @{ $modMeta->{author} },
$modMeta->{x_vcs}[15] . ' (last release only) <>'
unless (
@@ -1570,7 +1574,7 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
if ( defined( $moduleMaintainers{ $modMeta->{x_file}[4] } ) ) {
foreach (
split(
- '/', $moduleMaintainers{ $modMeta->{x_file}[4] }[1]
+ '/|,', $moduleMaintainers{ $modMeta->{x_file}[4] }[1]
)
)
{
@@ -1670,12 +1674,7 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
: ''
);
$modMeta->{resources}{repository}{x_raw} =
- 'https://svn.fhem.de/fhem/trunk/'
- . (
- $modMeta->{resources}{repository}{x_filepath} =~ /\/$/
- ? $modMeta->{resources}{repository}{x_filepath}
- : $modMeta->{resources}{repository}{x_filepath} . '/'
- )
+ 'https://svn.fhem.de/fhem/trunk/fhem/'
. $modMeta->{x_file}[1]
. $modMeta->{x_file}[2];
}
@@ -1712,67 +1711,15 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
&& defined( $modMeta->{resources}{x_support_community} )
&& $modMeta->{x_file}[2] ne 'fhem.pl' )
{
- if ( defined( $modMeta->{resources}{x_support_community}{board} )
- && $modMeta->{resources}{x_support_community}{board} ne '' )
+ foreach (
+ __GenerateKeywordsFromSupportCommunity(
+ $modMeta->{resources}{x_support_community}
+ )
+ )
{
- if (
- defined(
- $modMeta->{resources}{x_support_community}{subCommunity}
- )
- && defined(
- $modMeta->{resources}{x_support_community}{subCommunity}
- {board}
- )
- && $modMeta->{resources}{x_support_community}{subCommunity}
- {board} ne ''
- )
- {
- my $parent =
- lc( $modMeta->{resources}{x_support_community}{board} );
- my $tag =
- lc( $modMeta->{resources}{x_support_community}{subCommunity}
- {board} );
-
- $tag =~ s/$parent\s+-\s+|$parent\s+»\s+//g;
- $tag =~ s/ - |»/ /g;
- $tag =~ s/ +/-/g;
- $tag = 'fhem-' . $tag
- if ( $modMeta->{resources}{x_support_community}{cat} =~
- /^FHEM/i );
- $tag = 'cul-' . $tag
- if ( $modMeta->{resources}{x_support_community}{cat} =~
- /^CUL/i );
-
- push @{ $modMeta->{keywords} }, $tag
- if ( !defined( $modMeta->{keywords} )
- || !grep ( m/^$tag$/i, @{ $modMeta->{keywords} } ) );
- }
-
- my $tag = lc( $modMeta->{resources}{x_support_community}{board} );
- $tag =~ s/ - |»/ /g;
- $tag =~ s/ +/-/g;
- $tag = 'fhem-' . $tag
- if (
- $modMeta->{resources}{x_support_community}{cat} =~ /^FHEM/i );
- $tag = 'cul-' . $tag
- if ( $modMeta->{resources}{x_support_community}{cat} =~ /^CUL/i );
-
- push @{ $modMeta->{keywords} }, $tag
+ push @{ $modMeta->{keywords} }, $_
if ( !defined( $modMeta->{keywords} )
- || !grep ( m/^$tag$/i, @{ $modMeta->{keywords} } ) );
- }
-
- if ( defined( $modMeta->{resources}{x_support_community}{cat} )
- && $modMeta->{resources}{x_support_community}{cat} ne ''
- && $modMeta->{resources}{x_support_community}{cat} ne 'FHEM' )
- {
- my $tag = lc( $modMeta->{resources}{x_support_community}{cat} );
- $tag =~ s/ - |»/ /g;
- $tag =~ s/ +/-/g;
-
- push @{ $modMeta->{keywords} }, $tag
- if ( !defined( $modMeta->{keywords} )
- || !grep ( m/^$tag$/i, @{ $modMeta->{keywords} } ) );
+ || !grep ( m/^$_$/i, @{ $modMeta->{keywords} } ) );
}
}
@@ -1803,6 +1750,22 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
push @{ $modMeta->{keywords} }, "fhem-$modType-local";
}
+ # Add keywords to global index
+ if ( @{ $modMeta->{keywords} } > 0 ) {
+ foreach ( @{ $modMeta->{keywords} } ) {
+ if ( $modMeta->{x_file}[3] ) {
+ push @{ $keywords{$_}{modules} }, $modName
+ if ( !defined( $keywords{$_}{modules} )
+ || !grep ( /^$modName$/i, @{ $keywords{$_}{modules} } ) );
+ }
+ else {
+ push @{ $keywords{$_}{packages} }, $modName
+ if ( !defined( $keywords{$_}{packages} )
+ || !grep ( /^$modName$/i, @{ $keywords{$_}{packages} } ) );
+ }
+ }
+ }
+
# generate x_version
__SetXVersion($modMeta);
@@ -1810,6 +1773,58 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
return undef;
}
+sub __GenerateKeywordsFromSupportCommunity {
+ my ($community) = @_;
+ my @keywords;
+
+ if ( defined( $community->{board} )
+ && $community->{board} ne '' )
+ {
+ my $prefix;
+ $prefix = lc($1) . '-'
+ if ( $community->{cat} =~ /^(\w+)/ );
+
+ if ( defined( $community->{subCommunity} )
+ && defined( $community->{subCommunity}{board} )
+ && $community->{subCommunity}{board} ne '' )
+ {
+ my $parent = lc( $community->{board} );
+ my $tag = lc( $community->{subCommunity}{board} );
+
+ $tag =~ s/$parent\s+-\s+|$parent\s+»\s+//g;
+ $tag =~ s/ - |»/ /g;
+ $tag =~ s/ +/-/g;
+
+ foreach ( split '/', $tag ) {
+ push @keywords, $prefix . $_;
+ }
+ }
+
+ my $tag = lc( $community->{board} );
+ $tag =~ s/ - |»/ /g;
+ $tag =~ s/ +/-/g;
+
+ foreach ( split '/', $tag ) {
+ push @keywords, $prefix . $_;
+ }
+ }
+
+ if ( defined( $community->{cat} )
+ && $community->{cat} ne ''
+ && $community->{cat} ne 'FHEM' )
+ {
+ my $tag = lc( $community->{cat} );
+ $tag =~ s/ - |»/ /g;
+ $tag =~ s/ +/-/g;
+
+ foreach ( split '/', $tag ) {
+ push @keywords, $_;
+ }
+ }
+
+ return @keywords;
+}
+
sub __GetMaintainerdata {
return 0 unless ( __PACKAGE__ eq caller(0) );
my $fh;
@@ -1847,6 +1862,16 @@ sub __GetMaintainerdata {
|| ( $4 && $2 eq 'FHEM/' )
)
{
+ my $type = $4 ? 'module' : 'package';
+
+ if ( !-f $1 && !-f $1 . '.pm' ) {
+ Log 4,
+ __PACKAGE__
+ . "::__GetMaintainerdata ERROR: Orphan $type entry:\n "
+ . join( ' ', @line );
+ next;
+ }
+
$maintainer[0][0] = $1; # complete match
$maintainer[0][1] = $2; # relative file path
$maintainer[0][2] = $3; # file name
@@ -1860,6 +1885,8 @@ sub __GetMaintainerdata {
? 'deprecated'
: 'supported'; # Lifecycle status
+ my $modName = $maintainer[0][4];
+
$line[2] =~ s/\s*\(.*\)\s*$//; # remove all comments
$maintainer[3] =
$maintainer[2] eq 'deprecated'
@@ -1869,18 +1896,49 @@ sub __GetMaintainerdata {
if ( defined( $moduleMaintainers{ $maintainer[0][4] } ) ) {
Log 1,
__PACKAGE__
- . "::__GetMaintainerdata ERROR: Duplicate entry:\n"
- . ' 1st: '
+ . "::__GetMaintainerdata ERROR: Duplicate $type entry:\n"
+ . ' 1st: '
. $moduleMaintainers{ $maintainer[0][4] }[0][0] . ' '
. $moduleMaintainers{ $maintainer[0][4] }[1] . ' '
. $moduleMaintainers{ $maintainer[0][4] }[2]
- . "\n 2nd: "
+ . "\n 2nd: "
. join( ' ', @line );
}
else {
+ # Register in global FHEM module index
$moduleMaintainers{ $maintainer[0][4] } = \@maintainer;
- push @{ $maintainerModules{ $maintainer[1] } },
- $maintainer[0][4];
+
+ # Register in global maintainer index
+ foreach ( split '/|,', $maintainer[1] ) {
+ push @{ $maintainerModules{$_} }, $maintainer[0][4];
+ }
+
+ # Generate keywords for global index
+ foreach (
+ __GenerateKeywordsFromSupportCommunity(
+ $maintainer[3]
+ )
+ )
+ {
+ if ( $type eq 'module' ) {
+ push @{ $keywords{$_}{modules} },
+ $modName
+ if (
+ !defined( $keywords{$_}{modules} )
+ || !grep ( /^$modName$/i,
+ @{ $keywords{$_}{modules} } )
+ );
+ }
+ else {
+ push @{ $keywords{$_}{packages} },
+ $modName
+ if (
+ !defined( $keywords{$_}{packages} )
+ || !grep ( /^$modName$/i,
+ @{ $keywords{$_}{packages} } )
+ );
+ }
+ }
}
}
@@ -1888,6 +1946,17 @@ sub __GetMaintainerdata {
# used by FHEM modules.
# Packages must provide file extension here.
elsif ( $2 && $2 eq 'FHEM/' && $6 eq 'pm' ) {
+
+ my $type = 'package';
+
+ if ( !-f $1 && !-f $1 . '.pm' ) {
+ Log 4,
+ __PACKAGE__
+ . "::__GetMaintainerdata ERROR: Orphan $type entry:\n "
+ . join( ' ', @line );
+ next;
+ }
+
$maintainer[0][0] = $1; # complete match
$maintainer[0][1] = $2; # relative file path
$maintainer[0][2] = $3; # file name
@@ -1896,23 +1965,53 @@ sub __GetMaintainerdata {
$maintainer[0][4] = $5; # FHEM package name
$maintainer[0][5] = $6; # file extension
$maintainer[1] = $line[1]; # Maintainer alias name
- $maintainer[2] = $line[2]; # Forum support section
+ $maintainer[2] =
+ $line[2] =~ m/\(deprecated\)/i
+ ? 'deprecated'
+ : 'supported'; # Lifecycle status
+
+ my $modName = $maintainer[0][4];
+
+ $line[2] =~ s/\s*\(.*\)\s*$//; # remove all comments
+ $maintainer[3] =
+ $maintainer[2] eq 'deprecated'
+ ? ()
+ : __GetSupportForum( $line[2] ); # Forum support section
if ( defined( $packageMaintainers{ $maintainer[0][4] } ) ) {
Log 1,
__PACKAGE__
- . "::__GetMaintainerdata ERROR: Duplicate entry:\n"
- . ' 1st: '
+ . "::__GetMaintainerdata ERROR: Duplicate $type entry:\n"
+ . ' 1st: '
. $packageMaintainers{ $maintainer[0][4] }[0][0] . ' '
. $packageMaintainers{ $maintainer[0][4] }[1] . ' '
. $packageMaintainers{ $maintainer[0][4] }[2]
- . "\n 2nd: "
+ . "\n 2nd: "
. join( ' ', @line );
}
else {
+ # Register in global FHEM package index
$packageMaintainers{ $maintainer[0][4] } = \@maintainer;
- push @{ $maintainerPackages{ $maintainer[1] } },
- $maintainer[0][4];
+
+ # Register in global maintainer index
+ foreach ( split '/|,', $maintainer[1] ) {
+ push @{ $maintainerPackages{$_} },
+ $maintainer[0][4];
+ }
+
+ # Generate keywords for global index
+ foreach (
+ __GenerateKeywordsFromSupportCommunity(
+ $maintainer[3]
+ )
+ )
+ {
+ push @{ $keywords{$_}{packages} }, $modName
+ if ( !defined( $keywords{$_}{packages} )
+ || !
+ grep ( /^$modName$/i,
+ @{ $keywords{$_}{packages} } ) );
+ }
}
}
@@ -2417,7 +2516,7 @@ sub __SetXVersion {
"description": "n/a"
}
},
- "version": "v0.2.0",
+ "version": "v0.3.0",
"release_status": "testing",
"author": [
"Julian Pawlowski "