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/</</sg;
$d =~ s/>/>/sg;
$d =~ s/"/"/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;