File create-appdata-xml.pl of Package brp-extract-appdata

#!/usr/bin/perl -w
# search for files packaged more than once
# it is an error if such a file exists but the packages do not conflict
#
use strict;
use Data::Dumper;
use File::Glob;

sub _e {
  my ($d) = @_;
  $d =~ s/&/&/sg;
  $d =~ s/</&lt;/sg;
  $d =~ s/>/&gt;/sg;
  $d =~ s/"/&quot;/sg;
  return $d;
}

my $build_root = $::ENV{BUILD_ROOT} || '/';

my $TOPDIR = '/usr/src/packages';
$TOPDIR = '/.build.packages' if -d "$build_root/.build.packages";

open (ALL_RPMS, "chroot $build_root find $TOPDIR/RPMS/ -name \"*.rpm\" |");
my @rpms = <ALL_RPMS>;
chomp @rpms;
close ALL_RPMS;

my @appdata = glob("$build_root$TOPDIR/OTHER/*.applications");
if (@appdata != 1) {
  print STDERR "DEBUG: there is not a single *.applications file\n";
  exit 0;
}
my $appdata = shift @appdata;
open(APPDATA, "$appdata") || die "can't open $appdata";
my $currentfile = '';
my $indesktopentry = 0;
my %apphash;
my %fullfiles;

while ( <APPDATA> ) {
  chomp;
 
  if (m/^<<(.*)>>$/) {
     $currentfile = $1;
     $indesktopentry = 0;
     next;
  }
  
  unless ($currentfile) {
     print "ERROR: haven't seen a file before $_\n";
     exit 0;
  }
  
  my $content = $fullfiles{$currentfile} || '';
  $fullfiles{$currentfile} = $content . $_;
 
  if (m/^\[Desktop Entry\]\s*$/) {
     if ($indesktopentry) {
	print "ERROR: 2 desktop entries? I'm out\n";
        exit 0;
     }
     $indesktopentry = 1;
     next;
  } elsif (m/^\[/) {
    $indesktopentry = 0; 
    next;
  }
  next unless $indesktopentry;
  next unless (m/^([^=]*)=(.*)$/);
  my $key = lc($1);
  my $val = $2;
  $apphash{$currentfile}->{$key} = $val;
}

# we don't need to keep this around - beside for debugging
unlink $appdata;
my %applicationrpms;

# Mount /proc for rpm
system("mount -n -tproc none $build_root/proc");
for my $rpm (@rpms) {
    next if ($rpm =~ m/-debuginfo/ || $rpm =~ m/-debugsource/);
    open (FILES, "chroot $build_root rpm -qp --qf '[%{NAME} %{FILENAMES}\n]' $rpm|");
    my @files = <FILES>;
    chomp @files;
    close FILES;
    open (URL, "chroot $build_root rpm -qp --qf '%{URL}' $rpm|");
    chomp(my $url = <URL>);
    close URL; 
    $url = undef if $url eq '(none)';
    # ignore empty rpm as rpmlint will catch them
    @files = grep {!/^\(none\)/} @files;
    for my $file (@files) {
        next unless $file =~ /^(\S+) (.*)$/;
        my $rpmname = $1;
        my $filename = $2;
        if (defined $apphash{$filename}) {
		$apphash{$filename}->{pkgname} = $rpmname;
		$apphash{$filename}->{homepage} ||= $url;
		$applicationrpms{$rpmname} = 1;
		print "DEBUG " . Dumper($apphash{$filename});
        }
    }
}
system("umount $build_root/proc");

for my $rpmname (sort keys %applicationrpms) {
    my $output = "$build_root$TOPDIR/OTHER/$rpmname-appdata.xml";
    open(APPDATA, ">", "$output") || die "can't write to $output";
    print APPDATA "<?xml version='1.0'?>\n";
    print APPDATA "<applications version='0.1'>\n";

    my $applications_output = 0;

    for my $file (sort keys %apphash) {
        my $hash = $apphash{$file};
	next if (($hash->{nodisplay} || '') =~ m,true,i);
	next if ($hash->{pkgname} ne $rpmname);
	$applications_output++;
	print APPDATA "  <application>\n";
	$file =~ s,/usr/share/applications/,,;
	print APPDATA "    <id type='application'>" . _e($file) . "</id>\n";
	print APPDATA "    <pkgname>" . _e($hash->{pkgname}) . "</pkgname>\n";
	if ($hash->{name}) {
	    print APPDATA "    <name>" . _e($hash->{name}) . "</name>\n";
	}
	if ($hash->{comment}) {
	    print APPDATA "    <summary>" . _e($hash->{comment}) . "</summary>\n";
	}
	if ($hash->{keywords}) {
	    print APPDATA "    <keywords>\n";
	    for my $keyword (split(/\s*;\s*/, $hash->{keywords})) {
		print APPDATA "      <keyword>" . _e($keyword) . "</keyword>\n";
	    }
	    print APPDATA "    </keywords>\n";
	}
	if ($hash->{icon}) {
	    print APPDATA "    <icon type='embedded'>\n";
            print APPDATA "      <name>" . _e($hash->{icon}) . "</name>\n";
            for my $ifile (sort keys %fullfiles) {
		if ($ifile =~ m,$hash->{icon}\.(png|svg|svgz|xpm)$,) {
                   print APPDATA "      <filecontent file='$ifile'>\n";
                   print APPDATA $fullfiles{$ifile};
                   print APPDATA "      </filecontent>\n";
                }
            }
            print APPDATA "    </icon>\n";
	}
	print APPDATA "    <appcategories>\n";
	for my $keyword (split(/\s*;\s*/, $hash->{categories})) {
	    print APPDATA  "      <appcategory>" . _e($keyword) . "</appcategory>\n";
	}
	print APPDATA "    </appcategories>\n";
	if ($hash->{mimetype}) {
	    print APPDATA "    <mimetypes>\n";
	    for my $keyword (split(/\s*;\s*/, $hash->{mimetype})) {
		print APPDATA  "      <mimetype>" . _e($keyword) . "</mimetype>\n";
	    }
	    print APPDATA "    </mimetypes>\n";
	}
	if ($hash->{homepage}) {
	    print APPDATA "    <url type='homepage'>". _e($hash->{homepage}) . "</url>\n"
	}
	print APPDATA "  </application>\n";
    }

    print APPDATA "</applications>\n";
    close(APPDATA);

    if ($applications_output == 0) {
	print "DEBUG: removing empty XML\n";
	# all were nodisplay
	unlink($output);
	next;
    }

    # just for debug
    open(APPDATA, "<", $output);
    while ( <APPDATA> ) {
	print "XML: $_";
    }
    close(APPDATA);
}

exit 0;

openSUSE Build Service is sponsored by