Merge lp:~jeremy-munsch/synapse-project/improved-search2 into lp:synapse-project

Proposed by Jeremy Munsch on 2015-12-03
Status: Needs review
Proposed branch: lp:~jeremy-munsch/synapse-project/improved-search2
Merge into: lp:synapse-project
Diff against target: 179 lines (+104/-2)
2 files modified
src/core/desktop-file-service.vala (+56/-0)
src/plugins/desktop-file-plugin.vala (+48/-2)
To merge this branch: bzr merge lp:~jeremy-munsch/synapse-project/improved-search2
Reviewer Review Type Date Requested Status
Rico Tzschichholz 2015-12-03 Pending
Review via email: mp+279448@code.launchpad.net

Description of the change

* Add minimum MatchScore for given regex match : Using fuzzy only on title only
* Add Caseless Regex Compile Flag
* Add search in description, keywords, generic name, categories
* Comptes proportionnal relevancies for less valuable matches (categories, etc..)

For generic_name and keywords, it checks if locale is different than eng strings.
If so it takes the locale ones and add them to the english ones.
If not, it uses SUPPORTED_GETTEXT_DOMAINS_KEYS to add the available translations without any check though.

I believe I checked all I could to be compliant.

To post a comment you must log in.

Unmerged revisions

637. By Jeremy Munsch on 2015-12-03

* Add minimum MatchScore for given regex match : Using fuzzy only on title only
* Add Caseless Regex Compile Flag
* Add search in description, keywords, generic name, categories
* Comptes proportionnal relevancies for less valuable matches (categories, etc..)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/core/desktop-file-service.vala'
2--- src/core/desktop-file-service.vala 2015-11-14 20:58:02 +0000
3+++ src/core/desktop-file-service.vala 2015-12-03 14:45:08 +0000
4@@ -82,6 +82,7 @@
5 public string name { get; construct set; }
6 public string comment { get; set; default = ""; }
7 public string icon_name { get; construct set; default = ""; }
8+ public string generic_name { get; set; default = ""; }
9
10 public bool needs_terminal { get; set; default = false; }
11 public string filename { get; construct set; }
12@@ -93,6 +94,8 @@
13
14 public string[] actions = null;
15 public string[] mime_types = null;
16+ public string[] categories = null;
17+ public string[] keywords = null;
18
19 private string? name_folded = null;
20 public unowned string get_name_folded ()
21@@ -183,6 +186,55 @@
22 if (keyfile.has_key (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_ACTIONS))
23 actions = keyfile.get_string_list (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_ACTIONS);
24
25+ unowned string string_comparator = "";
26+ unowned string? textdomain = null;
27+ StringBuilder key_info_builder = new StringBuilder ();
28+ foreach (unowned string domain_key in DesktopFileService.SUPPORTED_GETTEXT_DOMAINS_KEYS)
29+ if (keyfile.has_key (KeyFileDesktop.GROUP, domain_key)) {
30+ textdomain = keyfile.get_string (KeyFileDesktop.GROUP, domain_key);
31+ break;
32+ }
33+
34+ if (keyfile.has_key (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_GENERIC_NAME))
35+ {
36+ key_info_builder.append (keyfile.get_string (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_GENERIC_NAME));
37+ string_comparator = keyfile.get_locale_string (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_GENERIC_NAME);
38+ if (key_info_builder.str.hash () != string_comparator.hash ())
39+ key_info_builder.append_c (' ').append (string_comparator);
40+ else if (textdomain != null)
41+ {
42+ key_info_builder.append_c (' ')
43+ .append (GLib.dgettext (textdomain, key_info_builder.str));
44+ }
45+ generic_name = key_info_builder.str;
46+ }
47+
48+ // categories are never translated
49+ if (keyfile.has_key (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_CATEGORIES))
50+ categories = keyfile.get_string_list (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_CATEGORIES);
51+
52+ if (keyfile.has_key (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_KEYWORDS))
53+ {
54+ string[] temp_keywords = keyfile.get_string_list (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_KEYWORDS);
55+ string[] locale_list = keyfile.get_locale_string_list (KeyFileDesktop.GROUP, KeyFileDesktop.KEY_KEYWORDS);
56+ if (string.joinv ("", temp_keywords).hash () != string.joinv ("", locale_list).hash ())
57+ {
58+ foreach (unowned string word in locale_list)
59+ {
60+ temp_keywords += word;
61+ }
62+ keywords = temp_keywords;
63+ }
64+ else if (textdomain != null)
65+ {
66+ foreach (unowned string word in temp_keywords)
67+ {
68+ locale_list += GLib.dgettext (textdomain, word).dup ();
69+ }
70+ keywords = locale_list;
71+ }
72+ }
73+
74 // special case these, people are using them quite often and wonder
75 // why they don't appear
76 if (filename.has_suffix ("gconf-editor.desktop") ||
77@@ -221,6 +273,10 @@
78 private Gee.Map<string, Gee.List<DesktopFileInfo>> exec_map;
79 private Gee.Map<string, DesktopFileInfo> desktop_id_map;
80 private Gee.MultiMap<string, string> mimetype_parent_map;
81+ public const string[] SUPPORTED_GETTEXT_DOMAINS_KEYS = {
82+ "X-Ubuntu-Gettext-Domain",
83+ "X-GNOME-Gettext-Domain"
84+ };
85
86 construct
87 {
88
89=== modified file 'src/plugins/desktop-file-plugin.vala'
90--- src/plugins/desktop-file-plugin.vala 2015-11-14 20:58:02 +0000
91+++ src/plugins/desktop-file-plugin.vala 2015-12-03 14:45:08 +0000
92@@ -42,6 +42,9 @@
93 public string title_unaccented { get; construct; }
94 public string desktop_id { get; construct; }
95 public string exec { get; construct; }
96+ public string generic_name_folded { get; set; }
97+ public string categories_string_folded { get; set; }
98+ public string keywords_string_folded { get; construct; }
99
100 public DesktopFileMatch (DesktopFileInfo info)
101 {
102@@ -59,6 +62,9 @@
103 title_folded = desktop_info.get_name_folded () ?? title.casefold ();
104 title_unaccented = Utils.remove_accents (title_folded);
105 desktop_id = "application://" + desktop_info.desktop_id;
106+ generic_name_folded = desktop_info.generic_name.casefold ();
107+ categories_string_folded = string.joinv (" ", desktop_info.categories).casefold ();
108+ keywords_string_folded = string.joinv (" ", desktop_info.keywords).casefold ();
109 }
110 }
111
112@@ -130,12 +136,20 @@
113 return r;
114 }
115
116+ /**
117+ * computes proportionnal relevancy
118+ */
119+ private int compute_proportional_match_score (int matcher_value, int average_score)
120+ {
121+ return (int)Math.floor ((long)matcher_value * average_score / MatchScore.HIGHEST);
122+ }
123+
124 private void full_search (Query q, ResultSet results,
125 MatcherFlags flags = 0)
126 {
127 // try to match against global matchers and if those fail, try also exec
128 var matchers = Query.get_matchers_for_query (q.query_string_folded,
129- flags);
130+ flags, RegexCompileFlags.CASELESS);
131
132 foreach (var dfm in desktop_files)
133 {
134@@ -153,12 +167,44 @@
135 matched = true;
136 break;
137 }
138- else if (unaccented_title != null && matcher.key.match (unaccented_title))
139+ if (unaccented_title != null && matcher.key.match (unaccented_title))
140 {
141 results.add (dfm, compute_relevancy (dfm, matcher.value - MatchScore.INCREMENT_SMALL));
142 matched = true;
143 break;
144 }
145+ if (dfm.generic_name_folded != null
146+ && matcher.value >= MatchScore.AVERAGE
147+ && matcher.key.match (dfm.generic_name_folded))
148+ {
149+ results.add (dfm, compute_relevancy (dfm, compute_proportional_match_score (matcher.value, MatchScore.AVERAGE)));
150+ matched = true;
151+ break;
152+ }
153+ if (dfm.keywords_string_folded != null
154+ && matcher.value >= MatchScore.AVERAGE
155+ && matcher.key.match (dfm.keywords_string_folded))
156+ {
157+ results.add (dfm, compute_relevancy (dfm, compute_proportional_match_score (matcher.value, MatchScore.AVERAGE)));
158+ matched = true;
159+ break;
160+ }
161+ if (dfm.categories_string_folded != null
162+ && matcher.value >= MatchScore.BELOW_AVERAGE
163+ && matcher.key.match (dfm.categories_string_folded))
164+ {
165+ results.add (dfm, compute_relevancy (dfm, compute_proportional_match_score (matcher.value, MatchScore.BELOW_AVERAGE)));
166+ matched = true;
167+ break;
168+ }
169+ if (dfm.description != null
170+ && matcher.value >= MatchScore.BELOW_AVERAGE
171+ && matcher.key.match (dfm.description.casefold ()))
172+ {
173+ results.add (dfm, compute_relevancy (dfm, compute_proportional_match_score (matcher.value, MatchScore.BELOW_AVERAGE)));
174+ matched = true;
175+ break;
176+ }
177 }
178 if (!matched && dfm.exec.has_prefix (q.query_string))
179 {