Hello community,
here is the log from the commit of package brp-extract-appdata for openSUSE:Factory checked in at 2014-03-02 18:22:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/brp-extract-appdata (Old)
and /work/SRC/openSUSE:Factory/.brp-extract-appdata.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "brp-extract-appdata"
Changes:
--------
--- /work/SRC/openSUSE:Factory/brp-extract-appdata/brp-extract-appdata.changes 2014-01-09 15:28:12.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.brp-extract-appdata.new/brp-extract-appdata.changes 2014-03-02 18:22:04.000000000 +0100
@@ -1,0 +2,7 @@
+Thu Feb 27 12:18:20 CET 2014 - mls@suse.de
+
+- rewrite brp-extract-appdata.pl and create-appdata-xml.pl so that
+ it does not invent appdata files, but just patches the missing
+ information into the files
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ brp-extract-appdata.pl ++++++
--- /var/tmp/diff_new_pack.PzvYLJ/_old 2014-03-02 18:22:05.000000000 +0100
+++ /var/tmp/diff_new_pack.PzvYLJ/_new 2014-03-02 18:22:05.000000000 +0100
@@ -22,11 +22,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-# find files and extract them for later processing
+# find appdata files and extract them for later processing
#
use File::Basename;
use File::Find;
use MIME::Base64;
+use Encode;
+
+use strict;
my $basedir=dirname($ENV{'RPM_SOURCE_DIR'}) . "/OTHER";
@@ -48,44 +51,135 @@
chdir("/" . $ENV{'RPM_BUILD_ROOT'});
my @icondirs;
-
for my $prefix (qw{/usr /opt/kde3 usr opt/kde3}) {
for my $suffix (qw{pixmaps icons/hicolor icons/crystalsvg icons/gnome}) {
- push(@icondirs, "$prefix/share/$suffix");
+ push @icondirs, "$prefix/share/$suffix" if -d "$prefix/share/$suffix";
}
}
-find(\&wanted, "usr/share/applications/");
-
-my @icons;
-sub wanted
-{
- return unless $_ =~ /\.desktop$/;
- print OUTPUT "<$File::Find::name>>\n";
- open(DESKTOP, $_) or return;
- while ( <DESKTOP> ) {
- if ($_ =~ /^Icon=(.*)$/) { push(@icons, $1); }
- print OUTPUT $_;
+sub slurp {
+ return undef unless open (my $f, '<', $_[0]);
+ my $content = do { local $/; <$f> };
+ close $f;
+ return $content;
+}
+
+sub parse_desktop_data {
+ my ($filename) = @_;
+ open (my $f, '<', $filename) or return {};
+ my $indesktopentry = 0;
+ my %res;
+ while (<$f>) {
+ chomp;
+ if (/^\[Desktop Entry\]\s*$/) {
+ $indesktopentry++;
+ next;
+ }
+ $indesktopentry++ if $indesktopentry && /^\[/;
+ next unless $indesktopentry == 1;
+ next unless (m/^([^=]*)=(.*)$/);
+ my ($k, $v) = ($1, $2);
+ $k =~ s/^([^\[]*)/lc($1)/e;
+ $res{$k} = $v;
}
- close(DESKTOP);
+ return \%res;
}
-our $icon;
+sub get_icon_data {
+ my ($iconname) = @_;
-sub outputicon
-{
- return unless ($_ =~ /^$icon\.(png|svg|svgz|xpm)$/ or $_ eq $icon);
- open(my $icon, '<', $_) or return;
- my $content = do { local $/; <$icon> };
- close($icon);
- my $fname = $File::Find::name;
- $fname = "/$fname" unless $fname =~ m,^/,;
- print OUTPUT "<<$fname>>\n";
- print OUTPUT encode_base64($content) . "\n";
+ my @locs;
+ find( { wanted => sub { push @locs, $_ if /\/$iconname(?:.png|.svg|.svgz|.xpm)?$/ }, no_chdir => 1}, @icondirs);
+
+ my %have;
+ my @res;
+ for my $loc (@locs) {
+ my $fn = $loc;
+ $fn =~ s/^\/?/\//;
+ next if $have{$fn};
+ my $content = slurp($loc);
+ next unless $content;
+ push @res, [ $fn, encode_base64($content) ];
+ $have{$fn} = 1;
+ }
+ return \@res;
}
-for $icon (@icons) {
- find(\&outputicon, @icondirs);
+sub escape {
+ my ($d) = @_;
+ $d =~ s/&/&/sg;
+ $d =~ s/</sg;
+ $d =~ s/>/>/sg;
+ $d =~ s/"/"/sg;
+ Encode::_utf8_on($d);
+ $d = encode('UTF-8', $d, Encode::FB_XMLCREF);
+ Encode::_utf8_off($d);
+ $d =~ s/[\000-\010\013\014\016-\037\177]//g; # can't have those...
+ return $d;
+}
+
+sub read_and_extend_appdata {
+ my ($appdatafile) = @_;
+
+ my $content = slurp($appdatafile);
+ return undef unless $content;
+ $appdatafile =~ s/.*appdata\///;
+ my $dd;
+ $dd = parse_desktop_data("usr/share/applications/$1") if $content =~ /(.*){'comment'} && $content !~ /{'comment'})."</summary>\n";
+ for (sort keys %$dd) {
+ next unless /^comment\[([a-zA-Z_]+)\]$/;
+ $xml .= " ".escape($dd->{$_})."</summary>\n" if $1 ne 'C';
+ }
+ $xml =~ s/\n$//s;
+ $content =~ s/(<\/id>.*)$/$1\n$xml/m;
+ }
+ if ($dd->{'name'} && $content !~ /{'name'})."</name>\n";
+ for (sort keys %$dd) {
+ next unless /^name\[([a-zA-Z_]+)\]$/;
+ $xml .= " ".escape($dd->{$_})."</name>\n" if $1 ne 'C';
+ }
+ $xml =~ s/\n$//s;
+ $content =~ s/(<\/id>.*)$/$1\n$xml/m;
+ }
+ $content =~ s/(<\/id>.*)$/$1\n <pkgname>appdata($appdatafile)<\/pkgname>/m;
+ if ($dd->{'keywords'} && $content !~ /{'keywords'});
+ $xml .= " </keywords>\n";
+ $content =~ s/^(\s*<\/application>)/$xml$1/m;
+ }
+ if ($dd->{'icon'} && $content !~ /{'icon'});
+ if ($idata && @$idata) {
+ my $xml = " <icon type='embedded'>\n <name>".escape($dd->{'icon'})."</name>\n";
+ $xml .= " <filecontent file='".escape($_->[0])."'>\n$_->[1] </filecontent>\n" for @$idata;
+ $xml .= " </icon>\n";
+ $content =~ s/^(\s*<\/application>)/$xml$1/m;
+ }
+ }
+ if ($dd->{'categories'} && $content !~ /{'categories'});
+ $xml .= " </appcategories>\n";
+ $content =~ s/^(\s*<\/application>)/$xml$1/m;
+ }
+ return $content;
}
-close(OUTPUT);
+my @appdatas;
+find( { wanted => sub { push @appdatas, $_ if /\.appdata\.xml$/ } , no_chdir => 1}, "usr/share/appdata/");
+
+print OUTPUT "<?xml version='1.0'?>\n";
+print OUTPUT "<applications version='0.1'>\n";
+for my $appdata (@appdatas) {
+ my $c = read_and_extend_appdata($appdata);
+ next unless $c;
+ $c =~ s/^<\?xml[^\n]*\n//s;
+ $c =~ s/\n?$/\n/s;
+ $c =~ s/^(\s*<)/ $1/mg;
+ print OUTPUT $c;
+}
+print OUTPUT "</applications>\n";
++++++ create-appdata-xml.pl ++++++
--- /var/tmp/diff_new_pack.PzvYLJ/_old 2014-03-02 18:22:05.000000000 +0100
+++ /var/tmp/diff_new_pack.PzvYLJ/_new 2014-03-02 18:22:05.000000000 +0100
@@ -1,12 +1,12 @@
#!/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
-#
+# read appsteam imput data and distribute the data into the
+# matching rpms
+
use strict;
use Data::Dumper;
use File::Glob;
-sub _e {
+sub escape {
my ($d) = @_;
$d =~ s/&/&/sg;
$d =~ s/</sg;
@@ -31,153 +31,56 @@
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;
+open(APPDATA, '<', $appdata) || die "can't open $appdata\n";
+my $content = do { local $/; <APPDATA> };
+close APPDATA;
+unlink $appdata;
+
+# remove start and end tags
+$content =~ s/.*\n\n//s;
+$content =~ s/<\/applications>\n$//s;
+
+# split into application chunks
+my @appdatas = split(/$/m;
+ $appmatches{"/usr/share/appdata/$1"} = $ad;
+}
+exit 0 unless %appmatches;
+my %appresults;
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});
- }
- }
-}
-
-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);
+ next if $rpm =~ m/-debuginfo/ || $rpm =~ m/-debugsource/ || $rpm =~ /src\.rpm$/;
+ open (FILES, "chroot $build_root rpm -qp --qf '[%{NAME} %{FILENAMES}\n]' $rpm|");
+ my @files = <FILES>;
+ chomp @files;
+ close FILES;
+ # ignore empty rpm as rpmlint will catch them
+ @files = grep {!/^\(none\)/} @files;
+ for my $file (@files) {
+ next unless $file =~ /^(\S+) (.*)$/;
+ my $rpmname = $1;
+ my $rpmfile = $2;
+ my $ad = $appmatches{$rpmfile};
+ next unless $ad;
+ my $rpmnamex = escape($rpmname);
+ next unless $ad =~ s/^ <pkgname>appdata\((.*)\)<\/pkgname>$/ <pkgname>$rpmnamex<\/pkgname>/m;
+ push @{$appresults{$rpmname}}, $ad;
+ }
}
-exit 0;
-
+for my $rpmname (sort keys %appresults) {
+ 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";
+ print APPDATA $_ for @{$appresults{$rpmname}};
+ print APPDATA "</applications>\n";
+ close APPDATA;
+}
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org