1 /** 2 * Getting applications paths where desktop files are stored. 3 * 4 * Authors: 5 * $(LINK2 https://github.com/FreeSlave, Roman Chistokhodov) 6 * Copyright: 7 * Roman Chistokhodov, 2015-2017 8 * License: 9 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 10 * See_Also: 11 * $(LINK2 https://www.freedesktop.org/wiki/Specifications/desktop-entry-spec/, Desktop Entry Specification) 12 */ 13 14 module desktopfile.paths; 15 16 private { 17 import isfreedesktop; 18 import xdgpaths; 19 20 import std.algorithm; 21 import std.array; 22 import std.path; 23 import std.range; 24 } 25 26 version(unittest) { 27 import std.process : environment; 28 29 package struct EnvGuard 30 { 31 this(string env, string newValue) { 32 envVar = env; 33 envValue = environment.get(env); 34 environment[env] = newValue; 35 } 36 37 ~this() { 38 if (envValue is null) { 39 environment.remove(envVar); 40 } else { 41 environment[envVar] = envValue; 42 } 43 } 44 45 string envVar; 46 string envValue; 47 } 48 } 49 50 /** 51 * Applications paths based on data paths. 52 * This function is available on all platforms, but requires dataPaths argument (e.g. C:\ProgramData\KDE\share on Windows) 53 * Returns: Array of paths, based on dataPaths with "applications" directory appended. 54 */ 55 string[] applicationsPaths(Range)(Range dataPaths) if (isInputRange!Range && is(ElementType!Range : string)) { 56 return dataPaths.map!(p => buildPath(p, "applications")).array; 57 } 58 59 /// 60 unittest 61 { 62 assert(equal(applicationsPaths(["share", buildPath("local", "share")]), [buildPath("share", "applications"), buildPath("local", "share", "applications")])); 63 } 64 65 static if (isFreedesktop) 66 { 67 /** 68 * ditto, but returns paths based on known data paths. 69 * This function is defined only on freedesktop systems to avoid confusion with other systems that have data paths not compatible with Desktop Entry Spec. 70 */ 71 @trusted string[] applicationsPaths() nothrow { 72 return xdgAllDataDirs("applications"); 73 } 74 75 /// 76 unittest 77 { 78 import std.process : environment; 79 auto dataHomeGuard = EnvGuard("XDG_DATA_HOME", "/home/user/data"); 80 auto dataDirsGuard = EnvGuard("XDG_DATA_DIRS", "/usr/local/data:/usr/data"); 81 82 assert(applicationsPaths() == ["/home/user/data/applications", "/usr/local/data/applications", "/usr/data/applications"]); 83 } 84 85 /** 86 * Path where .desktop files can be stored by user. 87 * This function is defined only on freedesktop systems. 88 * Note: it does not check if returned path exists and appears to be directory. 89 */ 90 @safe string writableApplicationsPath() nothrow { 91 return xdgDataHome("applications"); 92 } 93 94 /// 95 unittest 96 { 97 import std.process : environment; 98 auto dataHomeGuard = EnvGuard("XDG_DATA_HOME", "/home/user/data"); 99 assert(writableApplicationsPath() == "/home/user/data/applications"); 100 } 101 }