First pieces of .desktop file parser

This commit is contained in:
Matthias Klumpp 2016-03-05 03:17:43 +01:00
parent f328a2ad89
commit 5ff941fc5f
4 changed files with 145 additions and 6 deletions

View File

@ -37,7 +37,6 @@ public:
this ()
{
writeln ("HELLO THERE!");
}
~this ()

View File

@ -17,4 +17,116 @@
* along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
module ag.handler.desktopparser;
module ag.handler.desktopparser;
import std.path : baseName;
import std.uni : toLower;
import std.string : format;
import std.algorithm : startsWith;
import glib.KeyFile;
import appstream.Component;
import ag.result;
immutable DESKTOP_GROUP = "Desktop Entry";
private string getLocaleFromKey (string key)
{
return "C";
}
private string getValue (KeyFile kf, string key)
{
string val;
try {
val = kf.getString (DESKTOP_GROUP, key);
} catch {
val = null;
}
return val;
}
bool parseDesktopFile (GeneratorResult res, string fname, string data, bool ignore_nodisplay = false)
{
auto df = new KeyFile ();
try {
df.loadFromData (data, -1, GKeyFileFlags.NONE);
} catch (Exception e) {
// there was an error
res.addHint ("desktop-file-read-error", e.msg);
return false;
}
try {
// check if we should ignore this .desktop file
auto dtype = df.getString (DESKTOP_GROUP, "Type");
if (dtype.toLower () != "application") {
// ignore this file, it isn't describing an application
return false;
}
} catch {}
try {
auto nodisplay = df.getString (DESKTOP_GROUP, "NoDisplay");
if ((!ignore_nodisplay) && (nodisplay.toLower () == "true")) {
// we ignore this .desktop file, shouldn't be displayed
return false;
}
} catch {}
try {
auto asignore = df.getString (DESKTOP_GROUP, "X-AppStream-Ignore");
if (asignore.toLower () == "true") {
// this .desktop file should be excluded from AppStream metadata
return false;
}
} catch {
// we don't care if non-essential tags are missing.
// if they are not there, the file should be processed.
}
/* check this is a valid desktop file */
if (!df.hasGroup (DESKTOP_GROUP)) {
res.addHint ("desktop-file-error", format ("Desktop file '%s' is not a valid desktop file.", fname));
return false;
}
// make sure we have a valid component to work on
auto cpt = res.getComponent (fname);
if (cpt is null) {
auto fname_base = baseName (fname);
cpt = new Component ();
cpt.setId (fname_base);
cpt.setKind (ComponentKind.DESKTOP);
res.addComponent (cpt);
}
size_t dummy;
auto keys = df.getKeys (DESKTOP_GROUP, dummy);
foreach (string key; keys) {
if (key.startsWith ("Name")) {
auto locale = getLocaleFromKey (key);
cpt.setName (getValue (df, key), locale);
}
}
return true;
}
unittest
{
import std.stdio;
auto data = """
[Desktop Entry]
Name=FooBar
Name[de_DE]=FooBär
Summary=A foo-ish bar.
""";
auto res = new GeneratorResult ();
auto ret = parseDesktopFile (res, "foobar.desktop", data, false);
assert (ret == true);
}

View File

@ -27,11 +27,13 @@ class GeneratorHint
{
private:
string tag;
public:
this ()
this (string tag)
{
this.tag = tag;
}
}

View File

@ -21,16 +21,19 @@ module ag.result;
import std.stdio;
import std.string;
import ag.hint;
import std.array : empty;
import appstream.Component;
import ag.hint;
class GeneratorResult
{
private:
Component cpts[];
GeneratorHint hints[];
Component[string] cpts;
string[Component] cptGID;
GeneratorHint[] hints;
public:
@ -42,4 +45,27 @@ public:
{
return cpts.length == 0;
}
Component getComponent (string id)
{
auto ptr = (id in cpts);
if (ptr is null)
return null;
return *ptr;
}
void addComponent (Component cpt)
{
string cid = cpt.getId ();
if (cid.empty)
throw new Exception ("Can not add component without ID to results set.");
cpts[cid] = cpt;
}
void addHint (string tag, string msg)
{
auto hint = new GeneratorHint (tag);
hints ~= hint;
}
}