cookutils diff fix-desktop-file @ rev 769
Add fix-desktop-file: check and fix errors, warnings and apply hints in .desktop files
author | Aleksej Bobylev <al.bobylev@gmail.com> |
---|---|
date | Sat Nov 07 16:00:41 2015 +0200 (2015-11-07) |
parents | |
children | e177315d46eb |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/fix-desktop-file Sat Nov 07 16:00:41 2015 +0200 1.3 @@ -0,0 +1,304 @@ 1.4 +#!/bin/sh 1.5 +# 1.6 +# Description: 1.7 +# ----------- 1.8 +# There is a utility that allows you to check a lot of mistakes in the 1.9 +# '.desktop' files: `desktop-file-validate`. 1.10 +# This utility, `fix-desktop-file`, allows you to correct most errors 1.11 +# automatically. 1.12 +# 1.13 +# Using: 1.14 +# ----- 1.15 +# fix-desktop-file /path/to/desktop-file.desktop 1.16 +# All the changes are made at the place with the replacement of the original 1.17 +# file. 1.18 +# 1.19 +# License: 1.20 +# ------- 1.21 +# `fix-desktop-file` is a part of Cookutils suite for SliTaz GNU/Linux 1.22 +# and distributed under the same license as the Cookutils. 1.23 +# 1.24 +# Useful links: 1.25 +# ------------ 1.26 +# * <http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html> 1.27 +# * <http://standards.freedesktop.org/menu-spec/menu-spec-1.0.html> 1.28 +# 1.29 +# Author: 1.30 +# ------ 1.31 +# Aleksej Bobylev <al.bobylev@gmail.com>, November 2015. 1.32 + 1.33 + 1.34 +desktop="$1" 1.35 + 1.36 +busybox awk ' 1.37 +BEGIN { 1.38 + FS = "="; 1.39 + in_section = 0; 1.40 + Name = ""; 1.41 + Comment = ""; 1.42 + Icon = ""; 1.43 +} 1.44 + 1.45 +function handle_cats(x, y, yy) { 1.46 + split(y, yy, ";"); 1.47 + for(i in yy) { 1.48 + if (cats[x] && ! cats[yy[i]]) { 1.49 + printf "%s;", yy[i]; 1.50 + cats[yy[i]] = "printed"; 1.51 + } 1.52 + } 1.53 +} 1.54 + 1.55 +in_section == 1 { 1.56 + # remove Version and deprecated keys 1.57 + if ($0 ~ /^(Version|Protocols|Extensions|BinaryPattern|MapNotify|Patterns|DefaultApp|MiniIcon|TerminalOptions|Encoding|SwallowTitle|SwallowExec|SortOrder|FilePattern|MultipleArgs)[[:space:]]*=/) 1.58 + next; 1.59 + 1.60 + # process Icon 1.61 + if ($0 ~ /^Icon[[:space:]]*=/) { 1.62 + if (Icon) next; # Icon already printed 1.63 + Icon = gensub(/^[^=]+=[[:space:]]*/, "", ""); 1.64 + # remove icon extension for non-absolute path 1.65 + if ($0 ~ /^Icon[[:space:]]*=[^\/]*$/) 1.66 + sub(/\.(png|xpm|svg)$/, ""); 1.67 + } 1.68 + 1.69 + # fix boolean values 1.70 + if ($0 ~ /^(NoDisplay|Hidden|DBusActivatable|Terminal|StartupNotify)[[:space:]]*=/) { 1.71 + sub(/0/, "false"); sub(/False/, "false"); 1.72 + sub(/1/, "true"); sub(/True/, "true"); 1.73 + } 1.74 + 1.75 + # process Name 1.76 + if ($0 ~ /^Name[[:space:]]*=/) { 1.77 + if (Name) next; # Name already printed 1.78 + Name = gensub(/^[^=]+=[[:space:]]*/, "", ""); 1.79 + print; 1.80 + for (i in name) { 1.81 + if (name[i] && 1.82 + name[i] != Name) { # skip redundant 1.83 + printf "Name[%s]=%s\n", i, name[i]; 1.84 + } 1.85 + } 1.86 + next; 1.87 + } 1.88 + 1.89 + # process localized Names 1.90 + if ($0 ~ /^Name\[[^\]+\][[:space:]]*=/) { 1.91 + locale = gensub(/^[^\[]*\[([^\]+)\].*$/, "\\1", ""); 1.92 + value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", ""); 1.93 + if (name[locale]) next; # Name[locale] already printed 1.94 + name[locale] = value; 1.95 + if (Name && 1.96 + Name != value) { # skip redundant 1.97 + name[locale] = value; 1.98 + print; 1.99 + } 1.100 + if (comment[locale] && # print pending Comment[xx] 1.101 + tolower(comment[locale]) != tolower(name[locale])) 1.102 + printf "Comment[%s]=%s\n", locale, comment[locale]; 1.103 + next; 1.104 + } 1.105 + 1.106 + # process Comment 1.107 + if ($0 ~ /^Comment[[:space:]]*=/) { 1.108 + if (Comment) next; # Comment already printed 1.109 + Comment = gensub(/^[^=]+=[[:space:]]*/, "", ""); 1.110 + if (Comment == Name) { 1.111 + printf "%s (*)\n", $0; # Forgive redundant Comment: Comment[xx] required it 1.112 + } else { 1.113 + print; 1.114 + } 1.115 + for (i in comment) { 1.116 + if (comment[i] && 1.117 + tolower(comment[i]) != tolower(Comment) && 1.118 + tolower(comment[i]) != tolower(name[i])) { # skip redundant 1.119 + printf "Comment[%s]=%s\n", i, comment[i]; 1.120 + } 1.121 + } 1.122 + next; 1.123 + } 1.124 + 1.125 + # process localized Comments 1.126 + if ($0 ~ /^Comment\[[^\]+\][[:space:]]*=/) { 1.127 + locale = gensub(/^[^\[]*\[([^\]+)\].*$/, "\\1", ""); 1.128 + locomm = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", ""); 1.129 + if (comment[locale]) next; # Comment[locale] already printed 1.130 + comment[locale] = locomm; 1.131 + if (Comment && # pending until Comment appear 1.132 + name[locale] && # pending until Name[xx] appear 1.133 + tolower(locomm) != tolower(Comment) && 1.134 + tolower(locomm) != tolower(name[locale])) { # skip redundant 1.135 + comment[locale] = locomm; 1.136 + print; 1.137 + } 1.138 + next; 1.139 + } 1.140 + 1.141 + # process Categories list 1.142 + if ($0 ~ /^Categories[[:space:]]*=/) { 1.143 + value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", ""); 1.144 + split(value, categories, ";"); 1.145 + printf "Categories="; 1.146 + for (i in categories) { 1.147 + # skip empty (;;), Application(s), and repeated categories 1.148 + if (categories[i] && 1.149 + categories[i] != "Application" && 1.150 + categories[i] != "Applications" && 1.151 + ! cats[categories[i]]) { 1.152 + if (categories[i] == "Terminal") categories[i] = "ConsoleOnly" # Mistake 1.153 + if (categories[i] == "Multimedia") categories[i] = "AudioVideo" # Mistake 1.154 + gsub(/ /, "", categories[i]); 1.155 + printf "%s;", categories[i]; 1.156 + cats[categories[i]] = "printed"; 1.157 + } 1.158 + } 1.159 + # add main category if needed (http://standards.freedesktop.org/menu-spec/latest/apas02.html) 1.160 + handle_cats("Audio", "AudioVideo"); 1.161 + handle_cats("Video", "AudioVideo"); 1.162 + handle_cats("Building", "Development"); 1.163 + handle_cats("Debugger", "Development"); 1.164 + handle_cats("IDE", "Development"); 1.165 + handle_cats("GUIDesigner", "Development"); 1.166 + handle_cats("Profiling", "Development"); 1.167 + handle_cats("RevisionControl", "Development"); 1.168 + handle_cats("Translation", "Development"); 1.169 + handle_cats("Calendar", "Office"); 1.170 + handle_cats("ContactManagement", "Office"); 1.171 + handle_cats("Chart", "Office"); 1.172 + handle_cats("Finance", "Office"); 1.173 + handle_cats("FlowChart", "Office"); 1.174 + handle_cats("PDA", "Office"); 1.175 + handle_cats("Presentation", "Office"); 1.176 + handle_cats("Spreadsheet", "Office"); 1.177 + handle_cats("WordProcessor", "Office"); 1.178 + handle_cats("2DGraphics", "Graphics"); 1.179 + handle_cats("VectorGraphics", "Graphics;2DGraphics"); 1.180 + handle_cats("RasterGraphics", "Graphics;2DGraphics"); 1.181 + handle_cats("3DGraphics", "Graphics"); 1.182 + handle_cats("Scanning", "Graphics"); 1.183 + handle_cats("OCR", "Graphics;Scanning"); 1.184 + handle_cats("TextTools", "Utility"); 1.185 + handle_cats("DesktopSettings", "Settings"); 1.186 + handle_cats("HardwareSettings", "Settings"); 1.187 + handle_cats("Printing", "HardwareSettings;Settings"); 1.188 + handle_cats("PackageManager", "Settings"); 1.189 + handle_cats("Dialup", "Network"); 1.190 + handle_cats("InstantMessaging", "Network"); 1.191 + handle_cats("Chat", "Network"); 1.192 + handle_cats("IRCClient", "Network"); 1.193 + handle_cats("Feed", "Network"); 1.194 + handle_cats("FileTransfer", "Network"); 1.195 + handle_cats("News", "Network"); 1.196 + handle_cats("P2P", "Network"); 1.197 + handle_cats("RemoteAccess", "Network"); 1.198 + handle_cats("Telephony", "Network"); 1.199 + handle_cats("TelephonyTools", "Utility"); 1.200 + handle_cats("VideoConference", "Network"); 1.201 + handle_cats("WebBrowser", "Network"); 1.202 + handle_cats("Midi", "AudioVideo;Audio"); 1.203 + handle_cats("Mixer", "AudioVideo;Audio"); 1.204 + handle_cats("Sequencer", "AudioVideo;Audio"); 1.205 + handle_cats("Tuner", "AudioVideo;Audio"); 1.206 + handle_cats("TV", "AudioVideo;Video"); 1.207 + handle_cats("DiscBurning", "AudioVideo"); 1.208 + handle_cats("ActionGame", "Game"); 1.209 + handle_cats("AdventureGame", "Game"); 1.210 + handle_cats("ArcadeGame", "Game"); 1.211 + handle_cats("BoardGame", "Game"); 1.212 + handle_cats("BlocksGame", "Game"); 1.213 + handle_cats("CardGame", "Game"); 1.214 + handle_cats("KidsGame", "Game"); 1.215 + handle_cats("LogicGame", "Game"); 1.216 + handle_cats("RolePlaying", "Game"); 1.217 + handle_cats("Shooter", "Game"); 1.218 + handle_cats("Simulation", "Game"); 1.219 + handle_cats("SportsGame", "Game"); 1.220 + handle_cats("StrategyGame", "Game"); 1.221 + handle_cats("Archiving", "Utility"); 1.222 + handle_cats("Compression", "Utility;Archiving"); 1.223 + handle_cats("FileManager", "System;FileTools"); 1.224 + handle_cats("TerminalEmulator", "System"); 1.225 + handle_cats("Filesystem", "System"); 1.226 + handle_cats("Calculator", "Utility"); 1.227 + handle_cats("Clock", "Utility"); 1.228 + handle_cats("TextEditor", "Utility"); 1.229 + handle_cats("KDE", "Qt"); 1.230 + handle_cats("GNOME", "GTK"); 1.231 + handle_cats("XFCE", "GTK"); 1.232 + 1.233 + printf "\n"; 1.234 + next; 1.235 + } 1.236 + 1.237 + # process MimeType list 1.238 + if ($0 ~ /^MimeType[[:space:]]*=/) { 1.239 + value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", ""); 1.240 + value = gensub(/x-directory\/gnome-default-handler/, "inode/directory", "g", value); 1.241 + value = gensub(/x-directory\/normal/, "inode/directory", "g", value); 1.242 + gsub(/ /, "", value); 1.243 + split(value, mimetype, ";"); 1.244 + printf "MimeType="; 1.245 + for (i in mimetype) { 1.246 + # skip empty (;;), and repeated mimetypes 1.247 + if (mimetype[i] && 1.248 + ! mimes[mimetype[i]]) { 1.249 + printf "%s;", mimetype[i]; 1.250 + mimes[mimetype[i]] = "printed"; 1.251 + } 1.252 + } 1.253 + printf "\n"; 1.254 + next; 1.255 + } 1.256 + 1.257 + # process Keywords 1.258 + if ($0 ~ /^Keywords[[:space:]]*=/) { 1.259 + value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", ""); 1.260 + split(value, keywords, ";"); 1.261 + printf "Keywords="; 1.262 + for (i in keywords) { 1.263 + # skip empty (;;), and repeated keywords 1.264 + if (keywords[i] && 1.265 + ! keys[keywords[i]]) { 1.266 + printf "%s;", keywords[i]; 1.267 + keys[keywords[i]] = "printed"; 1.268 + } 1.269 + } 1.270 + printf "\n"; 1.271 + delete keys; 1.272 + next; 1.273 + } 1.274 + 1.275 + # process localized Keywords 1.276 + if ($0 ~ /^Keywords\[[^\]+\][[:space:]]*=/) { 1.277 + locale = gensub(/^[^\[]*\[([^\]+)\].*$/, "\\1", ""); 1.278 + lokeys = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", ""); 1.279 + split(lokeys, keywords, ";"); 1.280 + printf "Keywords[%s]=", locale; 1.281 + for (i in keywords) { 1.282 + # skip empty (;;), and repeated keywords 1.283 + if (keywords[i] && 1.284 + ! keys[keywords[i]]) { 1.285 + printf "%s;", keywords[i]; 1.286 + keys[keywords[i]] = "printed"; 1.287 + } 1.288 + } 1.289 + printf "\n"; 1.290 + delete keys; 1.291 + next; 1.292 + } 1.293 + 1.294 +} 1.295 + 1.296 +/^\[/ { 1.297 + in_section = 0; 1.298 +} 1.299 +/^\[Desktop Entry\]/ { 1.300 + in_section = 1; 1.301 +} 1.302 +{ 1.303 + print; 1.304 +} 1.305 +' "$desktop" > "$desktop.$$" 1.306 + 1.307 +mv -f "$desktop.$$" "$desktop"