我关闭了很多浏览器标签

2021-08-09 03:57:27

我在工作中广受赞誉,因为我能够打开许多浏览器选项卡。 (至少,这是我从“天哪,伙计,看看你的浏览器!”的频繁呼喊中得到的结果)尽管如此,我一直认为值得让我的标签总数倒计时。出于各种原因,我打开了标签。我正在处理但应该在某个时候完成的事情 这里的一个问题是,一旦选项卡的数量足够大,“清理 uptabs”就会从“找出哪个选项卡是哪种选项卡”的整个步骤开始. 我可以关闭它,因为我已经完成了吗?这是我应该阅读的东西吗?很快?总有一天?我需要改进我的实时习惯:完成后关闭事情,按目的将事情分组等等。不过,在那之前,我需要看看我什么时候让事情失控了。多年来,我一直认为,“我应该随着时间的推移可视化我的标签计数。”有一次我什至写了一些程序来提供帮助,但大约一周前我终于完成了整个事情。当我发推文时,我收到了一些“你是怎么做到的?”,所以我想我会写下来。这很简单,除了有点不。如果你看不出来,这张图是由 Grafana 生成的,这是一个数据可视化工具,可以生成各种系统数据的图表和许多其他可视化。所以,我需要设置 Grafana。这很简单,我使用了他们的免费云托管,但在 Linode 上设置 Grafana 也非常简单。基本上,您安装并告诉它从哪里获取数据。有很多 Grafanatutorials。我的 Grafana 指向 Prometheus。 Prometheus 是一个时间序列数据库,它通过点击 HTTP 端点来收集数据。为了彻底简化,如果您希望应用程序公开要收集的指标并在以后进行分析,您可以为其提供 HTTP 侦听器,该侦听器以特定格式回复数据。有很多 Prometheustutorials。我需要做的是提供一个可以提供 tabcounts 的 HTTP 服务。我选择了最简单的方法来提供该计数,意思是这样的响应:

几年前,当我最初考虑这样做时,我使用的是 Firefox。我倾向于每隔几年在 Chrome 和 Firefox 之间来回切换。在 Firefox 中,获取标签计数非常容易。在配置文件目录中,有一个名为 sessionstore-backups/recovery.jsonlz4 之类的文件。它的确切位置随着时间的推移而改变,但通常在您的配置文件中有一个 JSON 文件,您可以阅读该文件以查看选项卡。 Chrome 以一种看似令人讨厌的二进制格式存储其会话,称为 SSNS。我看着决定并呻吟着。我知道我可以编写一个浏览器扩展程序来获取标签计数,但我对两件事有一种模糊的不安感。首先,我不确定我是否有办法在 Chrome 中嵌入网络服务器来提供这些数据。这意味着我想将数据写入文件以通过其他方式作为服务器。这引起了我的第二个担忧:我怀疑我是否能够可靠地将选项卡计数从扩展写入文件。不过,我有一个闪现的灵感。如果出于某种仁慈,Chrome 可以通过 AppleScript 实现自动化,我可以试一试。我打开了 macOSScript 编辑器,按 Cmd-Shift-O 到“打开字典”,然后寻找 GoogleChrome。它在那里!它的自动化套件很小,但它暴露了窗口和选项卡。我能够编写这个 AppleScript:如果应用程序“Google Chrome”正在运行,则将 tabcount 设置为 0,然后告诉应用程序“Google Chrome”在 Windows 中重复 w 将 tabcount 设置为 tabcount +(w 的标签计数) end repeat end tellend 如果 AppleScript 是很奇怪,但我过去在将它用于许多小任务方面取得了不错的成功。现在,我倾向于做的是证明某些东西可以在 AppleScript 中工作,然后使用 JXA 将其移植到 JavaScript。 JXA 是“用于自动化的 JavaScript”,它只是“如果你可以编写 JavaScript 而不是 AppleScript 来做同样的事情会怎样?”这非常吸引人!JavaScript 是一种不那么奇怪的语言,您可以将 macOS 自动化与您用 JavaScript 编写的其他代码结合起来。不过,它并不完美。用来表示 AppleScriptableentities 的对象非常笨拙。他们不让你得到他们的属性列表,如果你猜测,它不会有太大帮助。 object.foo 将始终对函数求值,但该函数在调用时可能会抛出“无此类函数”异常。类数组对象不可迭代,因此您将执行大量循环索引而不是迭代值。不过,这还不错: let tabcount = 0;const Chrome = new Application("Google Chrome");if (Chrome.running()) { for (i in Chrome.windows) { tabcount += Chrome.windows [i].tabs.length; }}

“检查 Chrome 是否正在运行”这一步很重要。一方面,表现得好像退出 Chrome 并没有真正消除其标签的心理负担一样好。另一方面,使用 AppleScript 与未运行的应用程序对话将启动该应用程序,我肯定不希望那样。现在我有了计算标签的方法。我实际编写的代码有点不同,因为我收集了每个窗口选项卡计数的数组,以防万一我也想绘制它,但它很像上面的代码。现在我需要让它定期运行。最明显的选择是让它在 macOS 服务管理器 launchd 下运行。这将是非常明智的,但需要我考虑launchdconfiguration,我不喜欢这样做。我想过设置 daemontools 来运行我的主目录之外的东西。我必须从launchd运行它,但是一旦设置了它,我就不必再考虑它了。我什至不想考虑一次,想!我有另一个奇怪的认识。我使用了一个名为 Hammerspoon 的程序,它是一种用于执行 macOS 自动化的通用工具。我用它来注入一些菜单栏图标来重新组织我的桌面或运行计时器,并为一些东西设置键盘快捷键。在它的许多其他功能中,它具有用于嵌入式 HTTP 服务的设施。它还可以使用 JXA 运行 JavaScript。我写了这个: tabulator = hs.httpserver.new()tabulator:setPort(9876)tabulator:setCallback(function (method, path, headers, body) if (method == "GET") and (path == "/metrics ") then bool, tabcounts, descriptor = hs.osascript.javascript([[ const Chrome = new Application("/Applications/Google Chrome.app"); let tabCounts = []; if (Chrome.running()) { for (i 在 Chrome.windows 中) { tabCounts.push(Chrome.windows[i].tabs.length); } tabCounts.sort((a,b) => b - a); } tabCounts; ]]) 如果不是 bool然后返回 "Error\n", 500, {} end local sum = 0 for i, tabs in ipairs(tabcounts) do sum = sum + tabs end return "chrome_open_tabs " .. sum .. "\n", 200, { } else return "No good.\n", 404, {} endend)tabulator:start() 这会在端口 9876 上创建一个新的 HTTP 侦听器。如果它收到 /metrics 的 GET 请求,它会运行我的 JXA 来询问 Chrome(如果运行)关于它的标签计数。 hs.osascript.javascript 函数返回一个元组,第二项 init 是 JavaScript 代码的最后一条语句,我们已经结束了机智h tabCounts。如果代码运行没有错误,我会在 200 响应中返回我的指标。为了在本地收集这些信息,而不是让互联网上的任何人都触发此 JavaScript 运行,我在 MacBook 上有一个本地运行的 Prometheus 实例。它命中这个端点,然后将结果中继到我在云中的 Prometheus 实例。 Grafana 看着它,向我展示了我的标签计数。当它在红色时,我叹了口气,翻阅我的标签,尽我所能关闭。你可以看到我的标签计数崩溃了几次。首先,我关闭了明显的重复或死文件。后来,我完成了以 opentabs 为代表的简单任务。周末,我阅读了很多积压的文章并关闭了它们。现在我大约有 30 个标签,这对我来说可能是正确的数字。

我打算构建它来帮助我更好地在 Prometheus 和 Grafana 中做事情,但我认为它主要是一种有趣的奇怪的通用编程,我很喜欢它。这是一个很好的提醒,许多乏味的问题都有愚蠢的解决方案。