2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 03:06:37 +00:00

98_Installer: add metadata search

git-svn-id: https://svn.fhem.de/fhem/trunk@18944 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2019-03-17 14:46:16 +00:00
parent 84ab86a6b4
commit 25559ee5ac
2 changed files with 559 additions and 109 deletions

View File

@ -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 = '<html>';
$footer = '</html>';
}
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 = '<table class="block wide">';
$rowOpen = '<tr>';
$rowOpenEven = '<tr class="even">';
$rowOpenOdd = '<tr class="odd">';
$colOpen = '<td>';
$colOpenMinWidth = '<td style="min-width: 12em;">';
$txtOpen = "<b>";
$txtClose = "</b>";
$colClose = '</td>';
$rowClose = '</tr>';
$tableClose = '</table>';
$colorRed = '<span style="color:red">';
$colorGreen = '<span style="color:green">';
$colorClose = '</span>';
}
my $space = $html ? '&nbsp;' : ' ';
my $lb = $html ? '<br />' : "\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, '<h2>Search result: ' . $search . '</h2>';
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, '<h3>Devices</h3>' . $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 =
'<a href="/'
. $webname
. '?detail='
. $device
. $FW_CSRF . '">'
. $device . '</a>'
if ($html);
my $linkMod = $defs{$device}{TYPE};
$linkMod =
'<a href="/'
. $webname
. '?cmd=get '
. $hash->{NAME}
. ' showModuleInfo '
. $defs{$device}{TYPE}
. $FW_CSRF . '">'
. $defs{$device}{TYPE} . '</a>'
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, '<h3>Modules</h3>' . $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 =
'<a href="/'
. $webname
. '?cmd=get '
. $hash->{NAME}
. ' showModuleInfo '
. $module
. $FW_CSRF . '">'
. $module . '</a>'
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, '<h3>Keywords</h3>' unless ($foundKeywords);
$found++;
$foundKeywords++;
push @ret, '<h4>' . $keyword . '</h4>';
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 =
'<a href="/'
. $webname
. '?cmd=get '
. $hash->{NAME}
. ' showModuleInfo '
. $item
. $FW_CSRF . '">'
. $item . '</a>'
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 .=
'<a href="/'
. $webname
@ -1250,8 +1536,19 @@ sub CreateMetadataList ($$$) {
. '" target="_blank"'
. (
defined( $board->{description} )
? ' title="' . $board->{description} . '"'
: ''
? ' title="'
. $board->{description}
. '"'
: (
defined(
$modMeta->{resources}{x_support_community}
{description}
)
? ' title="'
. $modMeta->{resources}{x_support_community}
{description} . '"'
: ''
)
)
. '>'
. $title . '</a>';
@ -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 .=
'<a href="/'
. $webname
. '?cmd=get '
. $hash->{NAME}
. ' search '
. $keyword
. $FW_CSRF . '">'
. $keyword . '</a>';
}
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 <julian.pawlowski@gmail.com>"

View File

@ -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 <julian.pawlowski@gmail.com>"