diff options
Diffstat (limited to 'apps/src')
-rw-r--r-- | apps/src/application.vala | 118 | ||||
-rw-r--r-- | apps/src/apps.vala | 172 | ||||
-rw-r--r-- | apps/src/cli.vala | 66 | ||||
-rw-r--r-- | apps/src/config.vala.in | 6 | ||||
-rw-r--r-- | apps/src/meson.build | 77 |
5 files changed, 0 insertions, 439 deletions
diff --git a/apps/src/application.vala b/apps/src/application.vala deleted file mode 100644 index 5748fc6..0000000 --- a/apps/src/application.vala +++ /dev/null @@ -1,118 +0,0 @@ -namespace AstalApps { -public class Application : Object { - public DesktopAppInfo app { get; construct set; } - public int frequency { get; set; default = 0; } - public string name { get { return app.get_name(); } } - public string entry { get { return app.get_id(); } } - public string description { get { return app.get_description(); } } - public string wm_class { get { return app.get_startup_wm_class(); } } - public string executable { owned get { return app.get_string("Exec"); } } - public string icon_name { owned get { return app.get_string("Icon"); } } - - internal Application(string id, int? frequency = 0) { - Object(app: new DesktopAppInfo(id)); - this.frequency = frequency; - } - - public string get_key(string key) { - return app.get_string(key); - } - - public bool launch() { - try { - var s = app.launch(null, null); - ++frequency; - return s; - } catch (Error err) { - critical(err.message); - return false; - } - } - - public Score fuzzy_match(string term) { - var score = Score(); - if (name != null) - score.name = levenshtein(term, name); - if (entry != null) - score.entry = levenshtein(term, entry); - if (executable != null) - score.executable = levenshtein(term, executable); - if (description != null) - score.description = levenshtein(term, description); - - return score; - } - - public Score exact_match(string term) { - var score = Score(); - if (name != null) - score.name = name.down().contains(term.down()) ? 1 : 0; - if (entry != null) - score.entry = entry.down().contains(term.down()) ? 1 : 0; - if (executable != null) - score.executable = executable.down().contains(term.down()) ? 1 : 0; - if (description != null) - score.description = description.down().contains(term.down()) ? 1 : 0; - - return score; - } - - internal Json.Node to_json() { - return new Json.Builder() - .begin_object() - .set_member_name("name").add_string_value(name) - .set_member_name("entry").add_string_value(entry) - .set_member_name("executable").add_string_value(executable) - .set_member_name("description").add_string_value(description) - .set_member_name("icon_name").add_string_value(icon_name) - .set_member_name("frequency").add_int_value(frequency) - .end_object() - .get_root(); - } -} - -int min3(int a, int b, int c) { - return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c); -} - -double levenshtein(string s1, string s2) { - int len1 = s1.length; - int len2 = s2.length; - - int[, ] d = new int[len1 + 1, len2 + 1]; - - for (int i = 0; i <= len1; i++) { - d[i, 0] = i; - } - for (int j = 0; j <= len2; j++) { - d[0, j] = j; - } - - for (int i = 1; i <= len1; i++) { - for (int j = 1; j <= len2; j++) { - int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1; - d[i, j] = min3( - d[i - 1, j] + 1, // deletion - d[i, j - 1] + 1, // insertion - d[i - 1, j - 1] + cost // substitution - ); - } - } - - var distance = d[len1, len2]; - int max_len = len1 > len2 ? len1 : len2; - - if (max_len == 0) { - return 1.0; - } - - return 1.0 - ((double)distance / max_len); -} - -public struct Score { - double name; - double entry; - double executable; - double description; -} -} diff --git a/apps/src/apps.vala b/apps/src/apps.vala deleted file mode 100644 index 2a0d507..0000000 --- a/apps/src/apps.vala +++ /dev/null @@ -1,172 +0,0 @@ -namespace AstalApps { -public class Apps : Object { - private string cache_directory; - private string cache_file; - private List<Application> _list; - private HashTable<string, int> frequents { get; private set; } - - public bool show_hidden { get; set; } - public List<weak Application> list { owned get { return _list.copy(); } } - - public double min_score { get; set; default = 0.5; } - - public double name_multiplier { get; set; default = 2; } - public double entry_multiplier { get; set; default = 1; } - public double executable_multiplier { get; set; default = 1; } - public double description_multiplier { get; set; default = 0.5; } - - public bool include_name { get; set; default = true; } - public bool include_entry { get; set; default = false; } - public bool include_executable { get; set; default = false; } - public bool include_description { get; set; default = false; } - - construct { - cache_directory = Environment.get_user_cache_dir() + "/astal"; - cache_file = cache_directory + "/apps-frequents.json"; - frequents = new HashTable<string, int>(str_hash, str_equal); - - AppInfoMonitor.get().changed.connect(() => { - reload(); - }); - - if (FileUtils.test(cache_file, FileTest.EXISTS)) { - try { - uint8[] content; - File.new_for_path(cache_file).load_contents(null, out content, null); - - var parser = new Json.Parser(); - parser.load_from_data((string)content); - var obj = parser.get_root().get_object(); - foreach (var member in obj.get_members()) { - var v = obj.get_member(member).get_value().get_int64(); - frequents.set(member, (int)v); - } - } catch (Error err) { - critical("cannot read cache: %s\n", err.message); - } - } - - reload(); - } - - private double score (string search, Application a, bool exact) { - var am = exact ? a.exact_match(search) : a.fuzzy_match(search); - double r = 0; - - if (include_name) - r += am.name * name_multiplier; - if (include_entry) - r += am.entry * entry_multiplier; - if (include_executable) - r += am.executable * executable_multiplier; - if (include_description) - r += am.description * description_multiplier; - - return r; - } - - public List<weak Application> query(string? search = "", bool exact = false) { - if (search == null) - search = ""; - - var arr = list.copy(); - - // empty search, sort by frequency - if (search == "") { - arr.sort_with_data((a, b) => { - return (int)b.frequency - (int)a.frequency; - }); - - return arr; - } - - // single character, sort by frequency and exact match - if (search.length == 1) { - foreach (var app in list) { - if (score(search, app, true) == 0) - arr.remove(app); - } - - arr.sort_with_data((a, b) => { - return (int)b.frequency - (int)a.frequency; - }); - - return arr; - } - - // filter - foreach (var app in list) { - if (score(search, app, exact) < min_score) - arr.remove(app); - } - - // sort by score, frequency - arr.sort_with_data((a, b) => { - var s1 = score(search, a, exact); - var s2 = score(search, b, exact); - - if (s1 == s2) - return (int)b.frequency - (int)a.frequency; - - return s1 < s2 ? 1 : -1; - }); - - return arr; - } - - public List<weak Application> fuzzy_query(string? search = "") { - return query(search, false); - } - - public List<weak Application> exact_query(string? search = "") { - return query(search, true); - } - - public void reload() { - var arr = AppInfo.get_all(); - - _list = new List<Application>(); - foreach (var app in arr) { - if (!show_hidden && !app.should_show()) - continue; - - var a = new Application( - app.get_id(), - frequents.get(app.get_id()) - ); - a.notify.connect((pspec) => { - if (pspec.name != "frequency") - return; - - var f = frequents.get(app.get_id()); - frequents.set(app.get_id(), ++f); - - _list.sort((a, b) => { - return (int)a.frequency - (int)b.frequency; - }); - cache(); - }); - _list.append(a); - } - - cache(); - } - - private void cache() { - var json = new Json.Builder().begin_object(); - foreach (string key in frequents.get_keys()) - json.set_member_name(key).add_int_value(frequents.get(key)); - - try { - if (!FileUtils.test(cache_directory, FileTest.EXISTS)) - File.new_for_path(cache_directory).make_directory_with_parents(null); - - var generator = new Json.Generator(); - generator.set_root(json.end_object().get_root()); - FileUtils.set_contents_full(cache_file, generator.to_data(null)); - } catch (Error err) { - critical("cannot cache frequents: %s", err.message); - } - } -} -} diff --git a/apps/src/cli.vala b/apps/src/cli.vala deleted file mode 100644 index d926c87..0000000 --- a/apps/src/cli.vala +++ /dev/null @@ -1,66 +0,0 @@ -static bool help; -static bool version; -static string search; -static string launch; -static bool json; - -const OptionEntry[] options = { - { "version", 'v', OptionFlags.NONE, OptionArg.NONE, ref version, null, null }, - { "help", 'h', OptionFlags.NONE, OptionArg.NONE, ref help, null, null }, - { "search", 's', OptionFlags.NONE, OptionArg.STRING, ref search, null, null }, - { "launch", 'l', OptionFlags.NONE, OptionArg.STRING, ref launch, null, null }, - { "json", 'j', OptionFlags.NONE, OptionArg.NONE, ref json, null, null }, - { null }, -}; - -int main(string[] argv) { - try { - var opts = new OptionContext(); - opts.add_main_entries(options, null); - opts.set_help_enabled(false); - opts.set_ignore_unknown_options(false); - opts.parse(ref argv); - } catch (OptionError err) { - printerr (err.message); - return 1; - } - - if (help) { - print("Usage:\n"); - print(" %s [flags]\n\n", argv[0]); - print("Flags:\n"); - print(" -h, --help Print this help and exit\n"); - print(" -v, --version Print version number and exit\n"); - print(" -s, --search Sort by a search term\n"); - print(" -l, --launch Launch an application\n"); - print(" -j, --json Print list in json format\n"); - return 0; - } - - if (version) { - print(AstalApps.VERSION); - return 0; - } - - var apps = new AstalApps.Apps(); - - if (launch != null) { - apps.query(launch).first().data.launch(); - return 0; - } - - if (json) { - var b = new Json.Builder().begin_array(); - foreach (var app in apps.query(search)) - b.add_value(app.to_json()); - - var generator = new Json.Generator(); - generator.set_root(b.end_array().get_root()); - stdout.printf(generator.to_data(null)); - } else { - foreach (var app in apps.query(search)) - stdout.printf("%s\n", app.entry); - } - - return 0; -} diff --git a/apps/src/config.vala.in b/apps/src/config.vala.in deleted file mode 100644 index b3a9f49..0000000 --- a/apps/src/config.vala.in +++ /dev/null @@ -1,6 +0,0 @@ -namespace AstalApps { - public const int MAJOR_VERSION = @MAJOR_VERSION@; - public const int MINOR_VERSION = @MINOR_VERSION@; - public const int MICRO_VERSION = @MICRO_VERSION@; - public const string VERSION = "@VERSION@"; -} diff --git a/apps/src/meson.build b/apps/src/meson.build deleted file mode 100644 index e4f0d59..0000000 --- a/apps/src/meson.build +++ /dev/null @@ -1,77 +0,0 @@ -version_split = meson.project_version().split('.') -api_version = version_split[0] + '.' + version_split[1] -gir = 'AstalApps-' + api_version + '.gir' -typelib = 'AstalApps-' + api_version + '.typelib' - -config = configure_file( - input: 'config.vala.in', - output: 'config.vala', - configuration: { - 'VERSION': meson.project_version(), - 'MAJOR_VERSION': version_split[0], - 'MINOR_VERSION': version_split[1], - 'MICRO_VERSION': version_split[2], - }, -) - -deps = [ - dependency('glib-2.0'), - dependency('gobject-2.0'), - dependency('gio-unix-2.0'), - dependency('json-glib-1.0'), -] - -sources = [ - config, - 'apps.vala', - 'application.vala', - 'cli.vala', -] - -if get_option('lib') - lib = library( - meson.project_name(), - sources, - dependencies: deps, - vala_header: meson.project_name() + '.h', - vala_vapi: meson.project_name() + '-' + api_version + '.vapi', - vala_gir: gir, - version: meson.project_version(), - install: true, - install_dir: [true, true, true, true], - ) - - import('pkgconfig').generate( - lib, - name: meson.project_name(), - filebase: meson.project_name() + '-' + api_version, - version: meson.project_version(), - subdirs: meson.project_name(), - requires: deps, - install_dir: get_option('libdir') / 'pkgconfig', - ) - - custom_target( - typelib, - command: [ - find_program('g-ir-compiler'), - '--output', '@OUTPUT@', - '--shared-library', get_option('prefix') / get_option('libdir') / '@PLAINNAME@', - meson.current_build_dir() / gir, - ], - input: lib, - output: typelib, - depends: lib, - install: true, - install_dir: get_option('libdir') / 'girepository-1.0', - ) -endif - -if get_option('cli') - executable( - meson.project_name(), - ['cli.vala', sources], - dependencies: deps, - install: true, - ) -endif |