1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2014-2015 Richard Hughes <richard@hughsie.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.1+
6 */
7
8 #include <config.h>
9 #include <string.h>
10 #include <fnmatch.h>
11
12 #include <asb-plugin.h>
13
14 #define __APPSTREAM_GLIB_PRIVATE_H
15 #include <as-utils-private.h>
16 #include <as-app-private.h>
17
18 const gchar *
asb_plugin_get_name(void)19 asb_plugin_get_name (void)
20 {
21 return "desktop";
22 }
23
24 void
asb_plugin_add_globs(AsbPlugin * plugin,GPtrArray * globs)25 asb_plugin_add_globs (AsbPlugin *plugin, GPtrArray *globs)
26 {
27 asb_plugin_add_glob (globs, "/usr/share/applications/*.desktop");
28 asb_plugin_add_glob (globs, "/usr/share/applications/kde4/*.desktop");
29 }
30
31 static gboolean
asb_plugin_desktop_refine(AsbPlugin * plugin,AsbPackage * pkg,const gchar * filename,AsbApp * app,const gchar * tmpdir,GError ** error)32 asb_plugin_desktop_refine (AsbPlugin *plugin,
33 AsbPackage *pkg,
34 const gchar *filename,
35 AsbApp *app,
36 const gchar *tmpdir,
37 GError **error)
38 {
39 AsAppParseFlags parse_flags = AS_APP_PARSE_FLAG_USE_HEURISTICS |
40 AS_APP_PARSE_FLAG_ALLOW_VETO;
41 g_autoptr(AsApp) desktop_app = NULL;
42 g_autoptr(GdkPixbuf) pixbuf = NULL;
43
44 /* use GenericName fallback */
45 if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_USE_FALLBACKS))
46 parse_flags |= AS_APP_PARSE_FLAG_USE_FALLBACKS;
47
48 /* create app */
49 desktop_app = as_app_new ();
50 if (!as_app_parse_file (desktop_app, filename, parse_flags, error))
51 return FALSE;
52
53 /* copy all metadata */
54 as_app_subsume_full (AS_APP (app), desktop_app,
55 AS_APP_SUBSUME_FLAG_NO_OVERWRITE |
56 AS_APP_SUBSUME_FLAG_MERGE);
57
58 return TRUE;
59 }
60
61 gboolean
asb_plugin_process_app(AsbPlugin * plugin,AsbPackage * pkg,AsbApp * app,const gchar * tmpdir,GError ** error)62 asb_plugin_process_app (AsbPlugin *plugin,
63 AsbPackage *pkg,
64 AsbApp *app,
65 const gchar *tmpdir,
66 GError **error)
67 {
68 AsLaunchable *launchable;
69 gboolean found = FALSE;
70 guint i;
71 g_autoptr(GString) desktop_basename = NULL;
72 const gchar *app_dirs[] = {
73 "/usr/share/applications",
74 "/usr/share/applications/kde4",
75 NULL };
76
77 /* get the (optional) launchable to get the name of the desktop file */
78 launchable = as_app_get_launchable_by_kind (AS_APP (app), AS_LAUNCHABLE_KIND_DESKTOP_ID);
79 if (launchable != NULL) {
80 desktop_basename = g_string_new (as_launchable_get_value (launchable));
81 } else {
82 desktop_basename = g_string_new (as_app_get_id (AS_APP (app)));
83 if (!g_str_has_suffix (desktop_basename->str, ".desktop"))
84 g_string_append (desktop_basename, ".desktop");
85 }
86
87 /* use the .desktop file to refine the application */
88 for (i = 0; app_dirs[i] != NULL; i++) {
89 g_autofree gchar *fn = NULL;
90 fn = g_build_filename (tmpdir,
91 app_dirs[i],
92 desktop_basename->str,
93 NULL);
94 if (g_file_test (fn, G_FILE_TEST_EXISTS)) {
95 if (!asb_plugin_desktop_refine (plugin, pkg, fn,
96 app, tmpdir, error))
97 return FALSE;
98 found = TRUE;
99 }
100 }
101
102 /* required */
103 if (!found && as_app_get_kind (AS_APP (app)) == AS_APP_KIND_DESKTOP) {
104 g_set_error (error,
105 ASB_PLUGIN_ERROR,
106 ASB_PLUGIN_ERROR_FAILED,
107 "a desktop file is required for %s",
108 as_app_get_id (AS_APP (app)));
109 return FALSE;
110 }
111
112 return TRUE;
113 }
114