|
| 1 | +#!/usr/bin/env gjs |
| 2 | + |
| 3 | +const { GLib, Gio } = imports.gi |
| 4 | + |
| 5 | +const STDIN = new Gio.DataInputStream({ base_stream: new Gio.UnixInputStream({ fd: 0 }) }) |
| 6 | +const STDOUT = new Gio.DataOutputStream({ base_stream: new Gio.UnixOutputStream({ fd: 1 }) }) |
| 7 | + |
| 8 | +class App { |
| 9 | + constructor() { |
| 10 | + this.last_query = '' |
| 11 | + this.last_value = '' |
| 12 | + this.query_base = '' |
| 13 | + this.name_base = '' |
| 14 | + this.app_info = Gio.AppInfo.get_default_for_uri_scheme('https') |
| 15 | + } |
| 16 | + |
| 17 | + complete() { |
| 18 | + this.send({ event: "noop" }) |
| 19 | + } |
| 20 | + |
| 21 | + build_query() { |
| 22 | + return `${this.query_base}${encodeURIComponent(this.last_query)}` |
| 23 | + } |
| 24 | + |
| 25 | + query(input) { |
| 26 | + const delim_position = input.indexOf(' ') |
| 27 | + const key = input.substring(0, delim_position) |
| 28 | + this.last_query = input.substr(delim_position + 1).trim() |
| 29 | + |
| 30 | + switch (key) { |
| 31 | + case 'wiki': |
| 32 | + this.query_base = 'https://en.wikipedia.org/w/index.php?search=' |
| 33 | + this.name_base = 'Wikipedia' |
| 34 | + break |
| 35 | + |
| 36 | + case 'bing': |
| 37 | + this.query_base = 'https://www.bing.com/search?q=' |
| 38 | + this.name_base = 'Bing' |
| 39 | + break |
| 40 | + |
| 41 | + case 'ddg': |
| 42 | + this.query_base = 'https://www.duckduckgo.com/?q=' |
| 43 | + this.name_base = 'DuckDuckGo' |
| 44 | + break |
| 45 | + |
| 46 | + case 'google': |
| 47 | + this.query_base = 'https://www.google.com/search?q=' |
| 48 | + this.name_base = 'Google' |
| 49 | + break |
| 50 | + |
| 51 | + case 'yt': |
| 52 | + this.query_base = 'https://www.youtube.com/results?search_query=' |
| 53 | + this.name_base = 'YouTube' |
| 54 | + break |
| 55 | + |
| 56 | + case 'amazon': |
| 57 | + this.query_base = 'https://smile.amazon.com/s?k=' |
| 58 | + this.name_base = 'Amazon' |
| 59 | + break |
| 60 | + |
| 61 | + default: |
| 62 | + this.query_base = 'https://www.duckduckgo.com/?q=' |
| 63 | + this.name_base = 'DuckDuckGo' |
| 64 | + } |
| 65 | + |
| 66 | + const selections = [{ |
| 67 | + id: 0, |
| 68 | + description: this.build_query(), |
| 69 | + name: `${this.name_base}: ${this.last_query}`, |
| 70 | + icon: this.app_info.get_icon().to_string(), |
| 71 | + }] |
| 72 | + |
| 73 | + this.send({ event: "queried", selections }) |
| 74 | + } |
| 75 | + |
| 76 | + submit(_id) { |
| 77 | + try { |
| 78 | + GLib.spawn_command_line_async(`xdg-open ${this.build_query()}`) |
| 79 | + } catch (e) { |
| 80 | + log(`xdg-open failed: ${e} `) |
| 81 | + } |
| 82 | + |
| 83 | + this.send({ event: "close" }) |
| 84 | + } |
| 85 | + |
| 86 | + send(object) { |
| 87 | + STDOUT.write_bytes(new GLib.Bytes(JSON.stringify(object) + "\n"), null) |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | +function main() { |
| 92 | + /** @type {null | ByteArray} */ |
| 93 | + let input_array |
| 94 | + |
| 95 | + /** @type {string} */ |
| 96 | + let input_str |
| 97 | + |
| 98 | + /** @type {null | LauncherRequest} */ |
| 99 | + let event_ |
| 100 | + |
| 101 | + let app = new App() |
| 102 | + |
| 103 | + mainloop: |
| 104 | + while (true) { |
| 105 | + try { |
| 106 | + [input_array,] = STDIN.read_line(null) |
| 107 | + } catch (e) { |
| 108 | + break |
| 109 | + } |
| 110 | + |
| 111 | + input_str = imports.byteArray.toString(input_array) |
| 112 | + if ((event_ = parse_event(input_str)) !== null) { |
| 113 | + switch (event_.event) { |
| 114 | + case "complete": |
| 115 | + app.complete() |
| 116 | + break |
| 117 | + case "query": |
| 118 | + if (event_.value) app.query(event_.value) |
| 119 | + break |
| 120 | + case "quit": |
| 121 | + break mainloop |
| 122 | + case "submit": |
| 123 | + if (event_.id !== null) app.submit(event_.id) |
| 124 | + } |
| 125 | + } |
| 126 | + } |
| 127 | +} |
| 128 | + |
| 129 | +/** |
| 130 | + * Parses an IPC event received from STDIN |
| 131 | + * @param {string} input |
| 132 | + * @returns {null | LauncherRequest} |
| 133 | + */ |
| 134 | +function parse_event(input) { |
| 135 | + try { |
| 136 | + return JSON.parse(input) |
| 137 | + } catch (e) { |
| 138 | + log(`Input not valid JSON`) |
| 139 | + return null |
| 140 | + } |
| 141 | +} |
| 142 | + |
| 143 | +main() |
0 commit comments