diff --git a/build.sh b/build.sh index 17dd916..ebc23dd 100755 --- a/build.sh +++ b/build.sh @@ -61,4 +61,9 @@ if [[ " ${PARAMS[*]} " =~ " -r " ]]; then glib-compile-schemas schemas/; copy; restart; +fi + +if [[ " ${PARAMS[*]} " =~ " -c " ]]; then + glib-compile-schemas schemas/; + copy; fi \ No newline at end of file diff --git a/metadata.json b/metadata.json index 405a872..3bcea2e 100644 --- a/metadata.json +++ b/metadata.json @@ -10,5 +10,5 @@ ], "url": "https://github.com/cliffniff/media-controls", "uuid": "mediacontrols@cliffniff.github.com", - "version": 27 + "version": 29 } diff --git a/prefs.js b/prefs.js index 70caf27..e39ea08 100644 --- a/prefs.js +++ b/prefs.js @@ -8,7 +8,9 @@ const Me = ExtensionUtils.getCurrentExtension(); const Gettext = imports.gettext.domain("mediacontrols"); const _ = Gettext.gettext; -const { execCommunicate } = Me.imports.utils; +Gio._promisify(Gio.File.prototype, "query_info_async"); +Gio._promisify(Gio.File.prototype, "enumerate_children_async"); +Gio._promisify(Gio.File.prototype, "delete_async"); function init() { ExtensionUtils.initTranslations("mediacontrols"); @@ -798,10 +800,7 @@ class AdwPrefs { adwrow.add_suffix(blacklistentry); adwrow.activatable_widget = blacklistentry; group2.add(adwrow); - const blacklistbuttonadd = Gtk.Button.new_from_icon_name( - "list-add-symbolic", - Gtk.IconSize.BUTTON || Gtk.IconSize.NORMAL - ); + const blacklistbuttonadd = Gtk.Button.new_from_icon_name("list-add-symbolic"); blacklistbuttonadd.set_valign(Gtk.Align.CENTER); adwrow.add_suffix(blacklistbuttonadd); adwrow.activatable_widget = blacklistbuttonadd; @@ -846,29 +845,70 @@ class AdwPrefs { } async _getCacheSize() { - // Command: du -hs [data_directory]/media-controls | awk '{NF=1}1' try { - let dir = GLib.get_user_config_dir() + "/media-controls"; - const result = await execCommunicate(["/bin/bash", "-c", `du -hs ${dir} | awk '{NF=1}1'`]); - return result || "0K"; + const path = GLib.get_user_config_dir() + "/media-controls/cache"; + const directory = Gio.File.new_for_path(path); + const iterator = await directory.enumerate_children_async( + "standard::*", + Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, + GLib.PRIORITY_DEFAULT, + null + ); + + let sizeInBytes = 0; + + for await (const fileInfo of iterator) { + const fileType = fileInfo.get_file_type(); + if (fileType === Gio.FileType.REGULAR) { + const fileSize = fileInfo.get_size(); + sizeInBytes += fileSize; + } + } + + return this._bytesToSize(sizeInBytes); } catch (error) { logError(error); } } async _clearcache(widgetCacheSize, clearcachespinner) { - let dir = GLib.get_user_config_dir() + "/media-controls"; try { clearcachespinner.start(); - await execCommunicate(["rm", "-r", dir]); + + const path = GLib.get_user_config_dir() + "/media-controls/cache"; + const directory = Gio.File.new_for_path(path); + const iterator = await directory.enumerate_children_async( + "standard::*", + Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, + GLib.PRIORITY_DEFAULT, + null + ); + + const promises = []; + + for await (const fileInfo of iterator) { + const file = iterator.get_child(fileInfo); + promises.push(file.delete_async(GLib.PRIORITY_DEFAULT, null)); + } + + await Promise.all(promises); + widgetCacheSize.set_text(await this._getCacheSize()); clearcachespinner.stop(); } catch (error) { + logError(error); widgetCacheSize.set_text(_("Failed to clear cache")); clearcachespinner.stop(); } } + _bytesToSize(bytes) { + const sizes = ["Bytes", "KB", "MB", "GB", "TB"]; + if (bytes === 0) return "0 Bytes"; + const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); + return Math.round(bytes / Math.pow(1024, i)) + " " + sizes[i]; + } + _onclearcacheclicked(widgetCacheSize, clearcachespinner) { this._clearcache(widgetCacheSize, clearcachespinner); } diff --git a/utils.js b/utils.js index 7cd4080..2cf7cb9 100644 --- a/utils.js +++ b/utils.js @@ -108,51 +108,3 @@ var getRequest = (url) => { }); }); }; - -/** - * Executes a shell command asynchronously - * @param {Array} argv array of arguments - * @param {string?} input input to be given to the shell command - * @param {boolean?} cancellable whether the operation is cancellable - * @returns - */ -var execCommunicate = async (argv, input = null, cancellable = null) => { - let cancelId = 0; - let flags = Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_PIPE; - - if (input !== null) flags |= Gio.SubprocessFlags.STDIN_PIPE; - - let proc = new Gio.Subprocess({ - argv: argv, - flags: flags, - }); - proc.init(cancellable); - - if (cancellable instanceof Gio.Cancellable) { - cancelId = cancellable.connect(() => proc.force_exit()); - } - - return new Promise((resolve, reject) => { - proc.communicate_utf8_async(input, null, (proc, res) => { - try { - let [, stdout, stderr] = proc.communicate_utf8_finish(res); - let status = proc.get_exit_status(); - - if (status !== 0) { - throw new Gio.IOErrorEnum({ - code: Gio.io_error_from_errno(status), - message: stderr ? stderr.trim() : GLib.strerror(status), - }); - } - - resolve(stdout.trim()); - } catch (e) { - reject(e); - } finally { - if (cancelId > 0) { - cancellable.disconnect(cancelId); - } - } - }); - }); -};