This script aims to reduce (significantly) the warnings in kbuildsycoca4 (the program which rebuilds KDE system configuration cache) and consequently the size of logs by applying the following 4 fixes to the mime database and applications .desktop files:
[ul]
[li]Add comment field to Mime types which lack one[/li][li]Add missing trailing semicolon to non XDG compliant .desktop files[/li][li]Add empty Exec line to .desktop files which require one[/li][li]Replace type Application with Type Service in .desktop files where it conflicts with X-KDE-Library (basically all YaST desktop files under openSUSE!).[/li][/ul]
What you should know:
All these flaws produce warnings and no fatal errors. If you belong to the 80% of people who believe they should no try to fix a working system and never put their noze in logs … you can safely ignore this post. If however you like Nietzsche and are tired of warnings which don’t seem to make sense but fill the logs - as I see from time to time some people complaining about this - you might find some interest in such a script.
[ul]
[li]1 and 2 are safe and advisable.[/li][li]3 is a hack I figured out. [/li][li]4 is ‘experimental’ (or should I say more artistic than scientific?) Therefore it is commented out in the code posted below.[/li][/ul]
#! /bin/bash
#: Title : fixmime
#: Date Created: Sat Jan 8 06:48:59 PST 2011
#: Last Edit : Sat Jan 8 15:53:57 PST 2011
#: Author : please_try_again
#: Version : 1.0
#: Description : fixes some inconsistances in mime database and desktop files,
#: : reducing significantly the amount of warnings during
#: : KDE initialization (kbuildsycoca4 output)
#: usage : fixmime
#: options: : -u : reverses changes applied in YaST2 apps
#
# Copy and paste this text into a text file and save it in /usr/local/bin as the file fixmime
# change onwership to root and make it executable for the owner (root) and readable by all users.
# You run this script as root or sudo, as other users don't have right access to the .desktop files
# under /usr/share/applications, the ones this script aims to modify.
#
# su -l
# chown root:wheel /usr/local/bin/fixmime
# chmod 774 /usr/local/bin/fixmime
#
#
logFile=/tmp/kbuildsycoca4.log
mimeDir=/usr/share/mime
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# some missing comments for Mime types. You can add others (but you don't have to)
# Just replace the following invalid characters in variable names:
# "/" with "___"
# "." with "__"
# "-" with "_"
# For example for:
# application/vnd.ms-excel.sheet.binary.macroEnabled.12.xml
# You'll use the following variable name:
# application___vnd__ms_excel__sheet__binary__macroEnabled__12
application___vnd__ms_excel__sheet__binary__macroEnabled__12="Excel Binary Workbook"
application___vnd__ms_excel__sheet__macroEnabled__12="Macro-enabled Excel Spreadsheet"
application___vnd__ms_excel__template__macroEnabled__12="Macro-enabled Excel Spreadsheet Template"
application___vnd__ms_powerpoint__presentation__macroEnabled__12="Macro-enabled PowerPoint Presentation"
application___vnd__ms_powerpoint__slideshow__macroEnabled__12="Macro-enabled PowerPoint Slideshow"
application___vnd__ms_powerpoint__template__macroEnabled__12="Macro-enabled PowerPoint Presentation Template"
application___vnd__ms_word__document__macroEnabled__12="Macro-enabled Word Document"
application___vnd__ms_word__template__macroEnabled__12="Macro-enabled Word Document Template"
application___vnd__openxmlformats_officedocument__presentationml__template="Microsoft PowerPoint Presentation Template"
application___vnd__openxmlformats_officedocument__spreadsheetml__template="Microsoft Excel Worksheet Template"
application___vnd__openxmlformats_officedocument__wordprocessingml__template="Microsoft Word Document Template"
application___x_ssh_key="SSH Authentication Key"
application___x_pem_key="Privacy Enhanced Mail authentication key"
# Other missing comments will be inferred from Mime types' names.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Add missing comments in Mime types and update mime database
function addMimeComments {
printf "
* adding missing <comment> field
"
mimeType=($(awk '/[Mm]issing *<comment>/ {gsub(/"/,"",$NF) ; print $NF}' $logFile))
# add new mime types to Overrides.xml
cat > $mimeDir/packages/Overrides.xml <<EOFOVERRIDES | sort -u
`grep '<mime-type' $mimeDir/packages/Overrides.xml 2>/dev/null`
`for m in ${mimeType[li]} ; do[/li]c=$(echo ${m%.xml} | sed 's|/|___|g;s|\.|__|g;s|-|_|g') ; c=${!c}
C=$(echo ${m%.xml} | sed 's|.*/||;s|^x-||;s|-| |g;s|$| document|') ; c=${c:-$C}
sed "/DO NOT EDIT/d;/<?xml/d;s|\(<mime-type \).*\(type=.*>\)|\1\2<comment>$c</comment>|" $mimeDir/$m | tr -d "
" | sed 's|> *<|><|g;s/^/ /'
echo
done`
EOFOVERRIDES
cat > /tmp/Overrides.xml <<EOFOVERRIDES2
<?xml version='1.0' encoding='utf-8'?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
`grep '<mime-type' $mimeDir/packages/Overrides.xml 2>/dev/null`
</mime-info>
EOFOVERRIDES2
mv {/tmp,$mimeDir/packages}/Overrides.xml
# update mime database
update-mime-database $mimeDir
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Fix Xdg not compliant .desktop files by ending MimeType lines with a semicolon.
function makeXdgCompliant {
printf "
* fixing not XDG compliant .desktop files
"
cat <<EOFXDGCOMPLIANT | sh -
$(sed -n '/missing trailing semicolon/s|^.*List entry \(.*\) in "\([^"]*\)".*|if [ -f \2 ] ; then cp \2 \2.org \&\& sed "/^\1/s/\\\([^;]\\\)$/\\1;/" \2.org > \2 \&\& rm \2.org \&\& echo " - \2" ; fi |p' $logFile | sed 's| \(ServiceMenus\)| /usr/share/kde4/services/\1|g' | sort -u)
EOFXDGCOMPLIANT
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Fix .desktop files with missing Exec by Adding Exec=""
# I don't know if it's OK ... just figured out (?)
function addDummyExec {
printf "
* fixing .desktop files with missing Exec
"
cat <<EOFMISSINGEXEC | sh -
$(sed -n '/but no Exec line/s|^.*desktop entry file *"\(.*\)" *has Type= "Application".*|if [ -f \1 ] ; then grep -q "X-KDE-Library" \1 \|\| echo Exec=\\"\\" >> \1 \&\& echo " - \1" ; fi |p' $logFile | sort -u | sed '/YaST2/d')
EOFMISSINGEXEC
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Fix type "Application" / X-KDE-Library conflict in .desktop files
# by replacing type=Application with type=Service in these files
# I'm not aware of the consequences of doing that, although it
# doesn't seem to affect YaST functionality (for me).
#
# Option "-u" reverses these changes in YaST desktop files.
# Therefore using it only makes sense under openSUSE
function fixKdeLibrary {
printf "
* resolving X-KDE-Library/Application type conflicts.
"
case $1 in
-u)
[ -d /usr/share/applications/YaST2 ] || return
desktopFiles=$(find /usr/share/applications/YaST2 -exec grep -q "Type=Service" "{}" ";" -exec echo "{}" ";")
[ "$desktopFiles" ] || return
for f in $desktopFiles ; do
cp $f{,.org}
echo " - changing $f"
sed 's/Type *= *Service/Type=Application/' $f.org > $f
rm $f.org
done
;;
*)
desktopFiles=$(sed -n '/but also has a X-KDE-Library/s|.*desktop entry file "\(.*\.desktop\)".*|\1|p' $logFile | sort -u)
[ "$desktopFiles" ] || return
for f in $desktopFiles ; do
cp $f{,.org}
echo " - changing $f"
sed 's/Type *= *Application/Type=Service/' $f.org > $f
rm $f.org
done
;;
esac
}
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MAIN - BEGIN
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# exit if nor toot
[ $(id -u) -gt 0 ] && exec echo "This script can only be run by root"
# run kbuildsycoca4 once to find errors/warnings and write output in $logFile
which kbuildsycoca4 &> /dev/null || exec echo "kbuilsycoca4 not found: Script aborted."
kbuildsycoca4 --noincremental > $logFile 2>&1
# 1) Fix mime types with missing comments
grep -q '[Mm]issing *<comment>' $logFile && addMimeComments
# 2) Fix non XDG compliant .desktop files
grep -q 'missing trailing semicolon' $logFile && makeXdgCompliant
# 3) Fix .desktop files with missing exec line
grep -q 'but no Exec line' $logFile && addDummyExec
# 4) Fix "Application" / X-KDE-Library conflict in .desktop files
# grep -q 'also has a X-KDE-Library' $logFile && fixKdeLibrary $1
# 5) Show remaining warnings in kbuildsycoca4 output.
printf "
***************************************************************
The following files still contain errors:
"
kbuildsycoca4 --noincremental 2>&1 | sed 's|.*::||;s|\. .*|.|;/^$/d;/kbuildsycoca4 running/d' | sort -u
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# MAIN - END
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
More about 4.
kbuildsycoca4 complains about all YaST .desktop files in /usr/share/applications/YaST2 and outputs a warning for each of them. The trick is to replace the Type Application with the type Service. YaST developpers might have had a good reason to use type Application. Anyway, as far as I can tell, YaST modules work with the type Service and Kde doesn’t complain. I applied this change on all my openSUSE machines … However, since you can never be sure if you did a good job until sunset (not to mention that there are two moons on my planet), I added an option to reverse the changes: fixmime -u (just in case it would be needed). Actually, the output of
kbuildsycoca4 --noincremental 2>&1
after running fixmime and fixmime -u will show a huge difference in the quantity of warnings generated.
When I want to run YaST modules directly from wm menus (whether KDE, Gnome or another one), I leave the Type Application and remove the X-KDE-Library key, put the file in /usr/local/share/applications , following the warning which recommends to split those files. I first implemented this function in the script, but removed it afterwards, as I realised that nobody does that.
Put the script in /usr/local/bin or in your system path, make executable and run as root or sudo.
On slower systems, fixmime can take some time, specially if run outside of KDE (but KDE has to be installed, as the script parses kbuildsycoca4 output on standard error)
It is called “fixmime” because I started fixing mime types and ended up fixing desktop files.