rev |
line source |
al@769
|
1 #!/bin/sh
|
al@769
|
2 #
|
al@769
|
3 # Description:
|
al@769
|
4 # -----------
|
al@769
|
5 # There is a utility that allows you to check a lot of mistakes in the
|
al@769
|
6 # '.desktop' files: `desktop-file-validate`.
|
al@769
|
7 # This utility, `fix-desktop-file`, allows you to correct most errors
|
al@769
|
8 # automatically.
|
al@769
|
9 #
|
al@769
|
10 # Using:
|
al@769
|
11 # -----
|
al@769
|
12 # fix-desktop-file /path/to/desktop-file.desktop
|
al@769
|
13 # All the changes are made at the place with the replacement of the original
|
al@769
|
14 # file.
|
al@769
|
15 #
|
al@769
|
16 # License:
|
al@769
|
17 # -------
|
al@769
|
18 # `fix-desktop-file` is a part of Cookutils suite for SliTaz GNU/Linux
|
al@769
|
19 # and distributed under the same license as the Cookutils.
|
al@769
|
20 #
|
al@769
|
21 # Useful links:
|
al@769
|
22 # ------------
|
al@769
|
23 # * <http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.1.html>
|
al@769
|
24 # * <http://standards.freedesktop.org/menu-spec/menu-spec-1.0.html>
|
al@769
|
25 #
|
al@769
|
26 # Author:
|
al@769
|
27 # ------
|
al@769
|
28 # Aleksej Bobylev <al.bobylev@gmail.com>, November 2015.
|
al@769
|
29
|
al@769
|
30
|
al@769
|
31 desktop="$1"
|
al@769
|
32
|
al@769
|
33 busybox awk '
|
al@769
|
34 BEGIN {
|
al@769
|
35 FS = "=";
|
al@769
|
36 in_section = 0;
|
al@769
|
37 Name = "";
|
al@769
|
38 Comment = "";
|
al@769
|
39 Icon = "";
|
al@769
|
40 }
|
al@769
|
41
|
al@769
|
42 function handle_cats(x, y, yy) {
|
al@769
|
43 split(y, yy, ";");
|
al@769
|
44 for(i in yy) {
|
al@769
|
45 if (cats[x] && ! cats[yy[i]]) {
|
al@769
|
46 printf "%s;", yy[i];
|
al@769
|
47 cats[yy[i]] = "printed";
|
al@769
|
48 }
|
al@769
|
49 }
|
al@769
|
50 }
|
al@769
|
51
|
al@769
|
52 in_section == 1 {
|
al@769
|
53 # remove Version and deprecated keys
|
al@769
|
54 if ($0 ~ /^(Version|Protocols|Extensions|BinaryPattern|MapNotify|Patterns|DefaultApp|MiniIcon|TerminalOptions|Encoding|SwallowTitle|SwallowExec|SortOrder|FilePattern|MultipleArgs)[[:space:]]*=/)
|
al@769
|
55 next;
|
al@769
|
56
|
al@769
|
57 # process Icon
|
al@769
|
58 if ($0 ~ /^Icon[[:space:]]*=/) {
|
al@769
|
59 if (Icon) next; # Icon already printed
|
al@769
|
60 Icon = gensub(/^[^=]+=[[:space:]]*/, "", "");
|
al@769
|
61 # remove icon extension for non-absolute path
|
al@769
|
62 if ($0 ~ /^Icon[[:space:]]*=[^\/]*$/)
|
al@769
|
63 sub(/\.(png|xpm|svg)$/, "");
|
al@769
|
64 }
|
al@769
|
65
|
al@769
|
66 # fix boolean values
|
al@769
|
67 if ($0 ~ /^(NoDisplay|Hidden|DBusActivatable|Terminal|StartupNotify)[[:space:]]*=/) {
|
al@769
|
68 sub(/0/, "false"); sub(/False/, "false");
|
al@769
|
69 sub(/1/, "true"); sub(/True/, "true");
|
al@769
|
70 }
|
al@769
|
71
|
al@769
|
72 # process Name
|
al@769
|
73 if ($0 ~ /^Name[[:space:]]*=/) {
|
al@769
|
74 if (Name) next; # Name already printed
|
al@769
|
75 Name = gensub(/^[^=]+=[[:space:]]*/, "", "");
|
al@769
|
76 print;
|
al@769
|
77 next;
|
al@769
|
78 }
|
al@769
|
79
|
al@769
|
80 # process localized Names
|
al@769
|
81 if ($0 ~ /^Name\[[^\]+\][[:space:]]*=/) {
|
al@769
|
82 locale = gensub(/^[^\[]*\[([^\]+)\].*$/, "\\1", "");
|
al@769
|
83 value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", "");
|
al@769
|
84 if (name[locale]) next; # Name[locale] already printed
|
al@769
|
85 name[locale] = value;
|
al@769
|
86 if (Name &&
|
al@769
|
87 Name != value) { # skip redundant
|
al@769
|
88 print;
|
al@769
|
89 }
|
al@769
|
90 next;
|
al@769
|
91 }
|
al@769
|
92
|
al@769
|
93 # process Comment
|
al@769
|
94 if ($0 ~ /^Comment[[:space:]]*=/) {
|
al@769
|
95 if (Comment) next; # Comment already printed
|
al@769
|
96 Comment = gensub(/^[^=]+=[[:space:]]*/, "", "");
|
al@769
|
97 if (Comment == Name) {
|
al@769
|
98 printf "%s (*)\n", $0; # Forgive redundant Comment: Comment[xx] required it
|
al@769
|
99 } else {
|
al@769
|
100 print;
|
al@769
|
101 }
|
al@769
|
102 next;
|
al@769
|
103 }
|
al@769
|
104
|
al@769
|
105 # process localized Comments
|
al@769
|
106 if ($0 ~ /^Comment\[[^\]+\][[:space:]]*=/) {
|
al@769
|
107 locale = gensub(/^[^\[]*\[([^\]+)\].*$/, "\\1", "");
|
al@769
|
108 locomm = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", "");
|
al@769
|
109 if (comment[locale]) next; # Comment[locale] already printed
|
al@769
|
110 comment[locale] = locomm;
|
al@770
|
111 if (tolower(locomm) != tolower(Comment) &&
|
al@769
|
112 tolower(locomm) != tolower(name[locale])) { # skip redundant
|
al@769
|
113 comment[locale] = locomm;
|
al@769
|
114 print;
|
al@769
|
115 }
|
al@769
|
116 next;
|
al@769
|
117 }
|
al@769
|
118
|
al@769
|
119 # process Categories list
|
al@769
|
120 if ($0 ~ /^Categories[[:space:]]*=/) {
|
al@769
|
121 value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", "");
|
al@769
|
122 split(value, categories, ";");
|
al@769
|
123 printf "Categories=";
|
al@769
|
124 for (i in categories) {
|
al@769
|
125 # skip empty (;;), Application(s), and repeated categories
|
al@769
|
126 if (categories[i] &&
|
al@769
|
127 categories[i] != "Application" &&
|
al@769
|
128 categories[i] != "Applications" &&
|
al@769
|
129 ! cats[categories[i]]) {
|
al@769
|
130 if (categories[i] == "Terminal") categories[i] = "ConsoleOnly" # Mistake
|
al@769
|
131 if (categories[i] == "Multimedia") categories[i] = "AudioVideo" # Mistake
|
al@769
|
132 gsub(/ /, "", categories[i]);
|
al@769
|
133 printf "%s;", categories[i];
|
al@769
|
134 cats[categories[i]] = "printed";
|
al@769
|
135 }
|
al@769
|
136 }
|
al@769
|
137 # add main category if needed (http://standards.freedesktop.org/menu-spec/latest/apas02.html)
|
al@769
|
138 handle_cats("Audio", "AudioVideo");
|
al@769
|
139 handle_cats("Video", "AudioVideo");
|
al@769
|
140 handle_cats("Building", "Development");
|
al@769
|
141 handle_cats("Debugger", "Development");
|
al@769
|
142 handle_cats("IDE", "Development");
|
al@769
|
143 handle_cats("GUIDesigner", "Development");
|
al@769
|
144 handle_cats("Profiling", "Development");
|
al@769
|
145 handle_cats("RevisionControl", "Development");
|
al@769
|
146 handle_cats("Translation", "Development");
|
al@769
|
147 handle_cats("Calendar", "Office");
|
al@769
|
148 handle_cats("ContactManagement", "Office");
|
al@769
|
149 handle_cats("Chart", "Office");
|
al@769
|
150 handle_cats("Finance", "Office");
|
al@769
|
151 handle_cats("FlowChart", "Office");
|
al@769
|
152 handle_cats("PDA", "Office");
|
al@769
|
153 handle_cats("Presentation", "Office");
|
al@769
|
154 handle_cats("Spreadsheet", "Office");
|
al@769
|
155 handle_cats("WordProcessor", "Office");
|
al@769
|
156 handle_cats("2DGraphics", "Graphics");
|
al@769
|
157 handle_cats("VectorGraphics", "Graphics;2DGraphics");
|
al@769
|
158 handle_cats("RasterGraphics", "Graphics;2DGraphics");
|
al@769
|
159 handle_cats("3DGraphics", "Graphics");
|
al@769
|
160 handle_cats("Scanning", "Graphics");
|
al@769
|
161 handle_cats("OCR", "Graphics;Scanning");
|
al@769
|
162 handle_cats("TextTools", "Utility");
|
al@769
|
163 handle_cats("DesktopSettings", "Settings");
|
al@769
|
164 handle_cats("HardwareSettings", "Settings");
|
al@769
|
165 handle_cats("Printing", "HardwareSettings;Settings");
|
al@769
|
166 handle_cats("PackageManager", "Settings");
|
al@769
|
167 handle_cats("Dialup", "Network");
|
al@769
|
168 handle_cats("InstantMessaging", "Network");
|
al@769
|
169 handle_cats("Chat", "Network");
|
al@769
|
170 handle_cats("IRCClient", "Network");
|
al@769
|
171 handle_cats("Feed", "Network");
|
al@769
|
172 handle_cats("FileTransfer", "Network");
|
al@769
|
173 handle_cats("News", "Network");
|
al@769
|
174 handle_cats("P2P", "Network");
|
al@769
|
175 handle_cats("RemoteAccess", "Network");
|
al@769
|
176 handle_cats("Telephony", "Network");
|
al@769
|
177 handle_cats("TelephonyTools", "Utility");
|
al@769
|
178 handle_cats("VideoConference", "Network");
|
al@769
|
179 handle_cats("WebBrowser", "Network");
|
al@769
|
180 handle_cats("Midi", "AudioVideo;Audio");
|
al@769
|
181 handle_cats("Mixer", "AudioVideo;Audio");
|
al@769
|
182 handle_cats("Sequencer", "AudioVideo;Audio");
|
al@769
|
183 handle_cats("Tuner", "AudioVideo;Audio");
|
al@769
|
184 handle_cats("TV", "AudioVideo;Video");
|
al@769
|
185 handle_cats("DiscBurning", "AudioVideo");
|
al@769
|
186 handle_cats("ActionGame", "Game");
|
al@769
|
187 handle_cats("AdventureGame", "Game");
|
al@769
|
188 handle_cats("ArcadeGame", "Game");
|
al@769
|
189 handle_cats("BoardGame", "Game");
|
al@769
|
190 handle_cats("BlocksGame", "Game");
|
al@769
|
191 handle_cats("CardGame", "Game");
|
al@769
|
192 handle_cats("KidsGame", "Game");
|
al@769
|
193 handle_cats("LogicGame", "Game");
|
al@769
|
194 handle_cats("RolePlaying", "Game");
|
al@769
|
195 handle_cats("Shooter", "Game");
|
al@769
|
196 handle_cats("Simulation", "Game");
|
al@769
|
197 handle_cats("SportsGame", "Game");
|
al@769
|
198 handle_cats("StrategyGame", "Game");
|
al@769
|
199 handle_cats("Archiving", "Utility");
|
al@769
|
200 handle_cats("Compression", "Utility;Archiving");
|
al@769
|
201 handle_cats("FileManager", "System;FileTools");
|
al@769
|
202 handle_cats("TerminalEmulator", "System");
|
al@769
|
203 handle_cats("Filesystem", "System");
|
al@769
|
204 handle_cats("Calculator", "Utility");
|
al@769
|
205 handle_cats("Clock", "Utility");
|
al@769
|
206 handle_cats("TextEditor", "Utility");
|
al@769
|
207 handle_cats("KDE", "Qt");
|
al@769
|
208 handle_cats("GNOME", "GTK");
|
al@769
|
209 handle_cats("XFCE", "GTK");
|
al@769
|
210
|
al@769
|
211 printf "\n";
|
al@769
|
212 next;
|
al@769
|
213 }
|
al@769
|
214
|
al@769
|
215 # process MimeType list
|
al@769
|
216 if ($0 ~ /^MimeType[[:space:]]*=/) {
|
al@769
|
217 value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", "");
|
al@769
|
218 value = gensub(/x-directory\/gnome-default-handler/, "inode/directory", "g", value);
|
al@769
|
219 value = gensub(/x-directory\/normal/, "inode/directory", "g", value);
|
al@769
|
220 gsub(/ /, "", value);
|
al@769
|
221 split(value, mimetype, ";");
|
al@769
|
222 printf "MimeType=";
|
al@769
|
223 for (i in mimetype) {
|
al@769
|
224 # skip empty (;;), and repeated mimetypes
|
al@769
|
225 if (mimetype[i] &&
|
al@769
|
226 ! mimes[mimetype[i]]) {
|
al@769
|
227 printf "%s;", mimetype[i];
|
al@769
|
228 mimes[mimetype[i]] = "printed";
|
al@769
|
229 }
|
al@769
|
230 }
|
al@769
|
231 printf "\n";
|
al@769
|
232 next;
|
al@769
|
233 }
|
al@769
|
234
|
al@769
|
235 # process Keywords
|
al@769
|
236 if ($0 ~ /^Keywords[[:space:]]*=/) {
|
al@769
|
237 value = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", "");
|
al@769
|
238 split(value, keywords, ";");
|
al@769
|
239 printf "Keywords=";
|
al@769
|
240 for (i in keywords) {
|
al@769
|
241 # skip empty (;;), and repeated keywords
|
al@769
|
242 if (keywords[i] &&
|
al@769
|
243 ! keys[keywords[i]]) {
|
al@769
|
244 printf "%s;", keywords[i];
|
al@769
|
245 keys[keywords[i]] = "printed";
|
al@769
|
246 }
|
al@769
|
247 }
|
al@769
|
248 printf "\n";
|
al@769
|
249 delete keys;
|
al@769
|
250 next;
|
al@769
|
251 }
|
al@769
|
252
|
al@769
|
253 # process localized Keywords
|
al@769
|
254 if ($0 ~ /^Keywords\[[^\]+\][[:space:]]*=/) {
|
al@769
|
255 locale = gensub(/^[^\[]*\[([^\]+)\].*$/, "\\1", "");
|
al@769
|
256 lokeys = gensub(/^[^=]*=[[:space:]]*(.*)$/, "\\1", "");
|
al@769
|
257 split(lokeys, keywords, ";");
|
al@769
|
258 printf "Keywords[%s]=", locale;
|
al@769
|
259 for (i in keywords) {
|
al@769
|
260 # skip empty (;;), and repeated keywords
|
al@769
|
261 if (keywords[i] &&
|
al@769
|
262 ! keys[keywords[i]]) {
|
al@769
|
263 printf "%s;", keywords[i];
|
al@769
|
264 keys[keywords[i]] = "printed";
|
al@769
|
265 }
|
al@769
|
266 }
|
al@769
|
267 printf "\n";
|
al@769
|
268 delete keys;
|
al@769
|
269 next;
|
al@769
|
270 }
|
al@769
|
271
|
al@769
|
272 }
|
al@769
|
273
|
al@769
|
274 /^\[/ {
|
al@769
|
275 in_section = 0;
|
al@769
|
276 }
|
al@769
|
277 /^\[Desktop Entry\]/ {
|
al@769
|
278 in_section = 1;
|
al@769
|
279 }
|
al@769
|
280 {
|
al@769
|
281 print;
|
al@769
|
282 }
|
al@769
|
283 ' "$desktop" > "$desktop.$$"
|
al@769
|
284
|
al@769
|
285 mv -f "$desktop.$$" "$desktop"
|