├── .DS_Store
├── .gitignore
├── .ruby-version
├── README.md
├── Rakefile
├── config.yml
├── icons
├── auto.psd
└── battery.psd
├── screenshots
├── .DS_Store
├── Alfred_Preferences_Learning.png
├── battery_2.png
├── callback.png
├── filtered by query.png
├── glance.png
├── help.png
├── mixed top processes.png
├── top_sleep.png
└── workflow.png
├── top
├── .DS_Store
├── 2B8AA7B1-2F79-475C-ADEF-6EE35005FCBA.png
├── 2D963FB2-D9CA-4423-AD37-66DAA9B5C6A4.png
├── 65DAE3B3-5040-4117-A911-65EDE5765DC3.png
├── 7DC8A847-D1E3-4D91-B2B5-844E95E7F38A.png
├── Authenticate.app
│ └── Contents
│ │ ├── Info.plist
│ │ ├── MacOS
│ │ └── Authenticate
│ │ ├── PkgInfo
│ │ └── Resources
│ │ ├── en.lproj
│ │ ├── InfoPlist.strings
│ │ └── MainMenu.nib
│ │ ├── lock.icns
│ │ └── lock.png
├── C439BF3F-F4EF-43E6-BFD2-DF8837E2B120.png
├── C844DE84-FBA3-4500-9C91-2A43C2729C1D.png
├── CA714745-B63F-46C5-9D77-50C52956368C.png
├── Gemfile
├── Gemfile.lock
├── README.pdf
├── alfred2_top_workflow.rb
├── bin
│ ├── AirPodsPower.sh
│ ├── fans_tempsMonitor
│ ├── iosnoop.d
│ └── smc
├── glance.rb
├── icon.png
├── icon
│ ├── .DS_Store
│ ├── battery
│ │ ├── age.png
│ │ ├── airpods-2.png
│ │ ├── airpods-3.png
│ │ ├── airpods.png
│ │ ├── charging.png
│ │ ├── clock.png
│ │ ├── critical.png
│ │ ├── cycles.png
│ │ ├── full.png
│ │ ├── health.png
│ │ ├── low.png
│ │ ├── medium.png
│ │ ├── power.png
│ │ ├── serial.png
│ │ └── temp.png
│ ├── bluetooth
│ │ ├── AppleBluetoothHIDKeyboard.png
│ │ ├── BNBMouseDevice.png
│ │ └── BNBTrackpadDevice.png
│ ├── fan
│ │ ├── blue.png
│ │ ├── green.png
│ │ └── red.png
│ ├── process
│ │ ├── GPU.png
│ │ ├── auto.png
│ │ ├── cpu.png
│ │ ├── io.png
│ │ └── memory.png
│ └── temperature
│ │ └── GPU.png
├── info.plist
├── lsof.rb
├── setting.yaml
├── sudo.sh
├── top
└── update.json
└── version.json
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | top/bundle
2 | top/.bundle
3 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | system
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # System Monitor : An Alfred 3 Workflow.
2 |
3 | ### Take a glance at system performance. List/Kill Top Processes by Memory, Cpu or IO Usage.
4 |
5 | ###### Forked from Zhao Cai as Alfred 2 Top Workflow at https://github.com/zhaocai/alfred2-top-workflow
6 |
7 |
8 |
9 |
10 | ### [💾 Download](https://github.com/singhprd/system-monitor-alfred-workflow/releases/download/1/System.Monitor.alfredworkflow)
11 |
12 | - 1) List/Kill Top Processes by Memory/CPU/IO Usage
13 |
14 |
15 |
16 |
17 |
18 | - 2) Get a glance of system status including internal battery, fan speed, CPU/GPU Temperature, bluetooth battery, disk capacity, etc.
19 |
20 |
21 |
22 |
23 |
24 | ## Usage
25 |
26 | ### 0. Show Help
27 |
28 | Just type `-?`, `-h`, or `--help` after the keyword to show help.
29 |
30 |
31 |
32 |
33 |
34 | ### 1. Top Processes
35 |
36 | #### A. Keywords:
37 |
38 | ##### 1.) `top`: Show a mixed processes list based on top cpu/memory usage.
39 |
40 |
41 | ###### 1. `top -m`, `top --memory` to show processes ranked by memory usage
42 |
43 | ###### 2. `top -c`, `top --cpu`, to show processes ranked by cpu usage
44 |
45 | ###### 3. `top -i`, `top --io`, to show processes ranked by io usage with **callback** from top io trace collector.
46 |
47 | Top IO requires [DTrace][Dtrace] and it would take a while to finish. The new **callback** design is to run the job in he background and post a notification (OSX 10.8+) using notification center. Click on the notification to show the result in alfred.
48 |
49 | 
50 |
51 |
52 |
53 | ###### **Modifier Key**
54 |
55 | - `none` : The default action is to list files opened by process ID
56 | - `control` : Kill the selected process
57 | - `command` : kill forcefully (`kill -9`)
58 | - `alt` : Nice (lower) the selected process's cpu priority
59 | - `shift` : Search web for process information
60 |
61 |
62 | ##### 2.) `kill`: Filter process to kill.
63 |
64 | ###### **Modifier Key**
65 |
66 | - `none`: The default action is to kill by process ID
67 | - `command` : kill forcefully (`kill -9`)
68 |
69 | ##### 3.) `lsof`: List files opened by process id
70 |
71 | ###### **Modifier Key**
72 |
73 | - `none`: The default action is to reveal file in Finder
74 |
75 | #### B. Filter by Query
76 |
77 | ##### 1.) Type process name to filter
78 |
79 |
80 |
81 |
82 |
83 |
84 | ##### 2.) To search for process state, use **:idle**, **:sleep**, **:stopped**, **:zombie**, **:uninterruptible**, **:runnable**, etc.
85 |
86 |
87 |
88 |
89 |
90 | ### 2. Glance an Eye on your system
91 |
92 | #### A. Keywords:
93 |
94 | 1. `glance`: Show system information including internal battery, bluetooth battery, disk capacity, etc.
95 |
96 |
97 |
98 |
99 |
100 | #### B. Change Display Order
101 |
102 | 1. Activate `Alfred Preferences` → `Advanced` → `Top Result Keyword Latching`
103 |
104 | 
105 |
106 | 2. Hit `Enter` for the feedback item you wish to show up on the top.
107 |
108 |
109 |
110 | ## Installation
111 |
112 | Two ways are provided:
113 |
114 | 1. You can download the latest release from [here](https://github.com/singhprd/system-monitor-alfred-workflow/releases) and import into to Alfred. This method is suitable for **regular users**.
115 |
116 | 2. You can `git clone` or `fork` this repository and use `rake install` and `rake uninstall` to install. Check `rake -T` for available tasks.
117 | This method create a symlink to the alfred workflow directory: "~/Library/Application Support/Alfred 2/Alfred.alfredpreferences/workflows". This method is suitable for **developers**.
118 |
119 |
120 | ---
121 |
122 | ### Forked from Zhao Cai at https://github.com/zhaocai/alfred2--workflow
123 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems' unless defined? Gem # rubygems is only needed in 1.8
2 |
3 | require 'yaml'
4 | require 'plist'
5 |
6 | config_file = 'config.yml'
7 |
8 |
9 | # /Users/peter/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows
10 |
11 | workflow_home=File.expand_path("~/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows")
12 |
13 | $config = YAML.load_file(config_file)
14 | $config["bundleid"] = "#{$config["domain"]}.#{$config["id"]}"
15 | $config["plist"] = File.join($config["path"], "info.plist")
16 | $config["workflow_dbx"] = File.join(File.expand_path($config["dropbox"]), "/Alfred.alfredpreferences/workflows")
17 |
18 | # import sub-rakefiles
19 | FileList['*/Rakefile'].each { |file|
20 | import file
21 | }
22 |
23 | task :config do
24 |
25 | info = Plist::parse_xml($config["plist"])
26 | unless info['bundleid'].eql?($config["bundleid"])
27 | info['bundleid'] = $config["bundleid"]
28 | File.open($config["plist"], "wb") { |file| file.write(info.to_plist) }
29 | end
30 | end
31 |
32 | task :chdir => [:config] do
33 | chdir $config['path']
34 | end
35 |
36 | desc "Install Gems"
37 | task "bundle:install" => [:chdir] do
38 | sh %Q{bundle install --standalone --clean} do |ok, res|
39 | if ! ok
40 | puts "fail to install gems (status = #{res.exitstatus})"
41 | else
42 | sh %Q{find bundle -type d \\(-name vendor -o -name cache -o -name spec -o -name test \\) -print0 | xargs -0 rm -rf}
43 | end
44 | end
45 | end
46 |
47 | desc "Update Gems"
48 | task "bundle:update" => [:chdir] do
49 | sh %Q{bundle update && bundle install --standalone --clean} do |ok, res|
50 | if ! ok
51 | puts "fail to update gems (status = #{res.exitstatus})"
52 | else
53 | sh %Q{find bundle -type d \\( -name vendor -o -name cache -o -name spec -o -name test \\) -print0 | xargs -0 rm -rf}
54 | end
55 | end
56 | end
57 |
58 | desc "Generate Doc"
59 | task :doc do
60 | sh %Q{pandoc -f markdown -o "#{$config['path']}/README.pdf" README.md}
61 | end
62 | desc "Install to Alfred"
63 | task :install => [:config] do
64 | ln_sf File.expand_path($config["path"]), File.join(workflow_home, $config["bundleid"])
65 | end
66 |
67 | desc "Unlink from Alfred"
68 | task :uninstall => [:config] do
69 | rm File.join(workflow_home, $config["bundleid"])
70 | end
71 |
72 | desc "Install to Dropbox"
73 | task :dbxinstall => [:config] do
74 | ln_sf File.expand_path($config["path"]), File.join($config["workflow_dbx"], $config["bundleid"])
75 | end
76 |
77 | desc "Unlink from Dropbox"
78 | task :dbxuninstall => [:config] do
79 | rm File.join($config["workflow_dbx"], $config["bundleid"])
80 | end
81 |
82 | desc "Clean up all the extras"
83 | task :clean => [:config] do
84 | end
85 |
86 | desc "Remove any generated file"
87 | task :clobber => [:clean] do
88 | rmtree File.join($config["path"], ".bundle")
89 | rmtree File.join($config["path"], "bundle")
90 | end
91 |
92 |
93 |
--------------------------------------------------------------------------------
/config.yml:
--------------------------------------------------------------------------------
1 | --- # bundle id = domain.id
2 | path: top
3 | domain: me.zhaowu
4 | id: top
5 | dropbox: ~/Dropbox/Alfred
6 |
7 |
--------------------------------------------------------------------------------
/icons/auto.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/icons/auto.psd
--------------------------------------------------------------------------------
/icons/battery.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/icons/battery.psd
--------------------------------------------------------------------------------
/screenshots/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/.DS_Store
--------------------------------------------------------------------------------
/screenshots/Alfred_Preferences_Learning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/Alfred_Preferences_Learning.png
--------------------------------------------------------------------------------
/screenshots/battery_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/battery_2.png
--------------------------------------------------------------------------------
/screenshots/callback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/callback.png
--------------------------------------------------------------------------------
/screenshots/filtered by query.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/filtered by query.png
--------------------------------------------------------------------------------
/screenshots/glance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/glance.png
--------------------------------------------------------------------------------
/screenshots/help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/help.png
--------------------------------------------------------------------------------
/screenshots/mixed top processes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/mixed top processes.png
--------------------------------------------------------------------------------
/screenshots/top_sleep.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/top_sleep.png
--------------------------------------------------------------------------------
/screenshots/workflow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/screenshots/workflow.png
--------------------------------------------------------------------------------
/top/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/.DS_Store
--------------------------------------------------------------------------------
/top/2B8AA7B1-2F79-475C-ADEF-6EE35005FCBA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/2B8AA7B1-2F79-475C-ADEF-6EE35005FCBA.png
--------------------------------------------------------------------------------
/top/2D963FB2-D9CA-4423-AD37-66DAA9B5C6A4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/2D963FB2-D9CA-4423-AD37-66DAA9B5C6A4.png
--------------------------------------------------------------------------------
/top/65DAE3B3-5040-4117-A911-65EDE5765DC3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/65DAE3B3-5040-4117-A911-65EDE5765DC3.png
--------------------------------------------------------------------------------
/top/7DC8A847-D1E3-4D91-B2B5-844E95E7F38A.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/7DC8A847-D1E3-4D91-B2B5-844E95E7F38A.png
--------------------------------------------------------------------------------
/top/Authenticate.app/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildMachineOSBuild
6 | 11C74
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleDocumentTypes
10 |
11 | CFBundleExecutable
12 | Authenticate
13 | CFBundleIconFile
14 | lock.icns
15 | CFBundleIdentifier
16 | com.BinaryGhost.Authenticate
17 | CFBundleInfoDictionaryVersion
18 | 6.0
19 | CFBundleName
20 | Authenticate
21 | CFBundlePackageType
22 | APPL
23 | CFBundleShortVersionString
24 | 1.0
25 | CFBundleSignature
26 | ????
27 | CFBundleURLTypes
28 |
29 | CFBundleVersion
30 | 1
31 | DTCompiler
32 | com.apple.compilers.llvm.clang.1_0
33 | DTPlatformBuild
34 | 4B110
35 | DTPlatformVersion
36 | GM
37 | DTSDKBuild
38 | 11A511a
39 | DTSDKName
40 | macosx10.7
41 | DTXcode
42 | 0410
43 | DTXcodeBuild
44 | 4B110
45 | LSMinimumSystemVersion
46 | 10.7
47 | NSHumanReadableCopyright
48 | Copyright © 2011 Don Southard. All rights reserved.
49 | NSMainNibFile
50 | MainMenu
51 | NSPrincipalClass
52 | NSApplication
53 | NSServices
54 |
55 | UTExportedTypeDeclarations
56 |
57 | UTImportedTypeDeclarations
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/top/Authenticate.app/Contents/MacOS/Authenticate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/Authenticate.app/Contents/MacOS/Authenticate
--------------------------------------------------------------------------------
/top/Authenticate.app/Contents/PkgInfo:
--------------------------------------------------------------------------------
1 | APPL????
--------------------------------------------------------------------------------
/top/Authenticate.app/Contents/Resources/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/Authenticate.app/Contents/Resources/en.lproj/InfoPlist.strings
--------------------------------------------------------------------------------
/top/Authenticate.app/Contents/Resources/en.lproj/MainMenu.nib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/Authenticate.app/Contents/Resources/en.lproj/MainMenu.nib
--------------------------------------------------------------------------------
/top/Authenticate.app/Contents/Resources/lock.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/Authenticate.app/Contents/Resources/lock.icns
--------------------------------------------------------------------------------
/top/Authenticate.app/Contents/Resources/lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/Authenticate.app/Contents/Resources/lock.png
--------------------------------------------------------------------------------
/top/C439BF3F-F4EF-43E6-BFD2-DF8837E2B120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/C439BF3F-F4EF-43E6-BFD2-DF8837E2B120.png
--------------------------------------------------------------------------------
/top/C844DE84-FBA3-4500-9C91-2A43C2729C1D.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/C844DE84-FBA3-4500-9C91-2A43C2729C1D.png
--------------------------------------------------------------------------------
/top/CA714745-B63F-46C5-9D77-50C52956368C.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/CA714745-B63F-46C5-9D77-50C52956368C.png
--------------------------------------------------------------------------------
/top/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "plist"
4 | gem "alfred-workflow"
5 | gem 'mixlib-shellout'
6 | gem 'iStats', :git => 'https://github.com/singhprd/iStats'
7 |
--------------------------------------------------------------------------------
/top/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GIT
2 | remote: https://github.com/singhprd/iStats
3 | revision: 7b377e3ce2c0950adc418f3728a566c82f59e602
4 | specs:
5 | iStats (1.5.1)
6 | parseconfig (~> 1.0)
7 | sparkr (~> 0.4)
8 |
9 | GEM
10 | remote: https://rubygems.org/
11 | specs:
12 | alfred-workflow (2.0.5)
13 | fuzzy_match (>= 2.0.4)
14 | gyoku (>= 1.1.0)
15 | moneta (>= 0.7.19)
16 | nori (>= 2.3.0)
17 | plist (>= 3.1.0)
18 | terminal-notifier (>= 1.5.0)
19 | builder (3.2.3)
20 | fuzzy_match (2.1.0)
21 | gyoku (1.3.1)
22 | builder (>= 2.1.2)
23 | mixlib-shellout (2.3.2)
24 | moneta (1.0.0)
25 | nori (2.6.0)
26 | parseconfig (1.0.8)
27 | plist (3.3.0)
28 | sparkr (0.4.1)
29 | terminal-notifier (1.8.0)
30 |
31 | PLATFORMS
32 | ruby
33 |
34 | DEPENDENCIES
35 | alfred-workflow
36 | iStats!
37 | mixlib-shellout
38 | plist
39 |
40 | BUNDLED WITH
41 | 1.16.0.pre.3
42 |
--------------------------------------------------------------------------------
/top/README.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/README.pdf
--------------------------------------------------------------------------------
/top/alfred2_top_workflow.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # -*- coding: utf-8 -*-
3 |
4 | # ============== = ===========================================================
5 | # Description : Alfred 2 Top Processes Workflow
6 | # Author : Zhao Cai
7 | # HomePage : https://github.com/zhaocai/alfred2-top-workflow
8 | # Date Created : Sun 10 Mar 2013 09:59:48 PM EDT
9 | # Last Modified : Sat 30 Mar 2013 11:39:10 PM EDT
10 | # Tag : [ ruby, alfred, workflow ]
11 | # Copyright : © 2013 by Zhao Cai,
12 | # Released under current GPL license.
13 | # ============== = ===========================================================
14 |
15 | ($LOAD_PATH << File.expand_path("..", __FILE__)).uniq!
16 |
17 | require 'rubygems' unless defined? Gem # rubygems is only needed in 1.8
18 |
19 | require "bundle/bundler/setup"
20 | require "alfred"
21 |
22 | # require handler class on demand
23 | require 'alfred/handler/callback'
24 |
25 | require 'mixlib/shellout'
26 |
27 |
28 | class Integer
29 | def to_human
30 | units = ['', 'K', 'M', 'G', 'T', 'P']
31 |
32 | size, unit = units.reduce(self.to_f) do |(fsize, _), utype|
33 | fsize > 512 ? [fsize / 1024, utype] : (break [fsize, utype])
34 | end
35 |
36 | "#{size > 9 || size.modulo(1) < 0.1 ? '%d' : '%.1f'}%s" % [size, unit]
37 | end
38 | end
39 |
40 | class Top < ::Alfred::Handler::Base
41 |
42 | attr_accessor :ignored_processes, :vague_commands
43 |
44 | PS_State = {
45 | :main => {
46 | 'I' => ':idle',
47 | 'R' => ':runnable',
48 | 'S' => ':sleep',
49 | 'T' => ':stopped',
50 | 'U' => ':uninterruptible',
51 | 'Z' => ':zombie',
52 | '?' => ':unknown'
53 | },
54 | :additional => {
55 | '+' => 'foreground',
56 | '<' => 'raised priority',
57 | '>' => 'soft limit on memory',
58 | 'A' => 'random page replacement',
59 | 'E' => 'trying to exit',
60 | 'L' => 'page locked',
61 | 'N' => 'reduced priority',
62 | 'S' => 'FIO page replacement',
63 | 's' => 'session leader',
64 | 'V' => 'suspended',
65 | 'W' => 'swapped out',
66 | 'X' => 'being traced or debugged'
67 | }
68 | }
69 |
70 | def initialize(alfred, opts = {})
71 | super
72 | @settings = {
73 | :handler => 'Top'
74 | }.update(opts)
75 |
76 | # Ignore mds because its cpu usgae spikes the moment alfred calls the workflow
77 | @ignored_processes = ['Alfred 2', 'mds']
78 |
79 | # [TODO] load from @core.workflow_setting @zhaocai @start(2013-10-11)
80 | @vague_commands = [
81 | 'ruby' , 'java' , 'zsh', 'bash', 'python', 'pythonw', 'perl', 'rsync',
82 | 'macruby' , 'ctags', 'vim', 'Vim' , 'MacVim', 'ag' , 'node' , 'aria2c',
83 | 'osascript', 'caffeinate', 'sleep'
84 | ]
85 |
86 | @io_sample_interval = 15
87 | @callback = ::Alfred::Handler::Callback.new(alfred)
88 | @callback.register
89 | end
90 |
91 | def on_parser
92 | options.sort = :auto
93 | parser.on("-m", "--memory", "sort by memory usage") do
94 | options.sort = :memory
95 | end
96 | parser.on("-c", "--cpu", "sort by cpu usage") do
97 | options.sort = :cpu
98 | end
99 |
100 | parser.on("-i", "--io", "sort by io usage") do
101 | options.sort = :io
102 | end
103 | end
104 |
105 | def on_help
106 | [
107 | {
108 | :kind => 'text' ,
109 | :title => '-c, --cpu [query]' ,
110 | :subtitle => 'Sort top processes based on cpu ussage.' ,
111 | :autocomplete => "-c #{query}"
112 | },
113 | {
114 | :kind => 'text' ,
115 | :title => '-m, --memory [query]' ,
116 | :subtitle => 'Sort top processes based on memory ussage.' ,
117 | :autocomplete => "-m #{query}"
118 | },
119 | {
120 | :kind => 'text' ,
121 | :title => '-i, --io [query]' ,
122 | :subtitle => 'Sort top processes based on io ussage.' ,
123 | :autocomplete => "-i #{query}"
124 | },
125 | ]
126 | end
127 |
128 |
129 |
130 | def generate_feedback(processes)
131 | processes.each_pair do |_, ps|
132 | if ps[:ignore?]
133 | ps[:order] = ps[:order] + 10
134 | end
135 |
136 | if ps[:icon]
137 | icon = ps[:icon]
138 | else
139 | icon = {:type => "default", :name => "icon/process/#{ps[:type]}.png"}
140 | end
141 | arg = xml_builder(
142 | :handler => @settings[:handler] ,
143 | :type => ps[:type] ,
144 | :name => ps[:command] ,
145 | :pid => ps[:pid]
146 | )
147 |
148 | feedback.add_item({
149 | :title => ps[:title] ,
150 | :subtitle => ps[:subtitle] ,
151 | :arg => arg ,
152 | :order => ps[:order] ,
153 | :icon => icon ,
154 | :match? => :all_title_match? ,
155 | })
156 | end
157 | end
158 |
159 |
160 | def on_feedback
161 | case options.sort
162 | when :auto
163 | psm = list_processes(:memory)
164 | psc = list_processes(:cpu)
165 |
166 | processes = {}
167 | psc.each_pair do |id, p|
168 | m = psm[id]
169 | if m
170 | p[:type] = :auto
171 | p[:title] = "#{p[:order]}/#{m[:order]}: #{p[:command]}"
172 | p[:order] = combined_order(p[:order], m[:order])
173 | end
174 | processes[id] = p
175 | end
176 | generate_feedback(processes)
177 | when :memory
178 | generate_feedback(list_processes(:memory))
179 | when :cpu
180 | generate_feedback(list_processes(:cpu))
181 | when :io
182 | arg = xml_builder(
183 | :handler => @settings[:handler] ,
184 | :task => 'callback',
185 | :type => 'iotop'
186 | )
187 |
188 | feedback.add_item({
189 | :title => "Collect IO trace to show top IO usage?" ,
190 | :subtitle => "Wait for callback after #{@io_sample_interval} seconds." ,
191 | :icon => ::Alfred::Feedback.CoreServicesIcon('GenericQuestionMarkIcon') ,
192 | :arg => arg ,
193 | })
194 | end
195 | end
196 |
197 | def on_action(arg)
198 | return unless action?(arg)
199 |
200 | if arg[:task] == 'callback'
201 | case arg[:type]
202 | when 'iotop'
203 |
204 | generate_feedback(iotop)
205 | callback_entry = {
206 | :key => arg[:type],
207 | :title => "Top Workflow Callback",
208 | :subtitle => "IO Top",
209 | }
210 |
211 | @callback.on_callback('top', callback_entry, feedback.items )
212 | end
213 |
214 | else
215 | case options.modifier
216 | when :control
217 | run_and_message("kill #{arg[:pid]}")
218 | when :command
219 | run_and_message("kill -9 #{arg[:pid]}")
220 | when :alt
221 | run_and_message("renice -n 5 #{arg[:pid]}")
222 | when :shift
223 | Alfred::Util.google(%Q{Mac "#{arg[:name]}" process})
224 | when :none
225 | Alfred.search("lsof #{arg[:pid]}")
226 | end
227 | end
228 | end
229 |
230 |
231 | def iotop
232 |
233 | iosnoop_command = %q{./sudo.sh ./bin/iosnoop.d 2>/dev/null}
234 | iosnoop = Mixlib::ShellOut.new(iosnoop_command)
235 | iosnoop.timeout = @io_sample_interval
236 |
237 | ps = {}
238 | begin
239 | iosnoop.run_command
240 | rescue Mixlib::ShellOut::CommandTimeout
241 | iosnoop.stdout.each_line do |line|
242 | columns = line.force_encoding(Encoding::UTF_8).split('⟩').map(&:strip)
243 |
244 | pid = columns[0].to_i
245 | type = columns[1]
246 | size = columns[2].to_i
247 | command = columns[3]
248 |
249 | if ps.has_key?(pid)
250 | p = ps[pid]
251 | else
252 | p = {
253 | :pid => pid ,
254 | :type => :io ,
255 | :command => command ,
256 | :read_size => 0 ,
257 | :write_size => 0 ,
258 | }
259 | end
260 |
261 | case type
262 | when 'R'
263 | p[:read_size] += size
264 | when 'W'
265 | p[:write_size] += size
266 | end
267 |
268 | ps[pid] = p
269 | end
270 | end
271 |
272 | return [] if ps.empty?
273 | ranks = {}
274 | i = 1
275 | ps.sort_by { |_, p| p[:read_size] + p[:write_size] }.reverse.each do |pair|
276 | ranks[pair[0]] = i
277 | i += 1
278 | end
279 | ps.each do |_, p|
280 | if p[:pid] > 0
281 | command_line = interpret_command(p, :use_command_line => true).to_s
282 |
283 | m = command_line.match(/(.*\.app\/).*/)
284 | p[:icon] = {:type => "fileicon", :name => m[1]} if m
285 | end
286 |
287 | p[:order] = ranks[p[:pid]]
288 | p[:title] = "#{p[:order]}: #{p[:command]}"
289 | p[:subtitle] = "Read: #{p[:read_size].to_human} ↔ Write: #{p[:write_size].to_human}"
290 | end
291 |
292 | return ps
293 | end
294 |
295 |
296 | private
297 |
298 | def combined_order(by_cpu, by_memory)
299 | order = by_cpu + by_memory
300 | if by_cpu < 3 or by_memory < 3
301 | order = 10 if order > 10
302 | else
303 | order += 10
304 | end
305 | order
306 | end
307 |
308 |
309 | def list_processes(type)
310 |
311 | type2opt = {:memory => 'm', :cpu => 'r'}
312 |
313 | cmd = %Q{ps -a#{type2opt[type]}wwwxo 'pid nice %cpu %mem state comm'}
314 | ps = Mixlib::ShellOut.new(cmd)
315 | ps.run_command
316 |
317 | lines = ps.stdout.lines.map(&:chomp)
318 | lines.shift
319 |
320 | processes = {}
321 | i = 1
322 | lines.each do |entry|
323 | columns = entry.split
324 |
325 | process = {
326 | :line => entry ,
327 | :type => type ,
328 | :order => i ,
329 | :pid => columns[0] ,
330 | :nice => columns[1] ,
331 | :cpu => columns[2] ,
332 | :memory => columns[3] ,
333 | :state => interpret_state(columns[4]) ,
334 | :command => columns[5..-1].join(" ") ,
335 | }
336 |
337 |
338 | process[:icon] = {:type => "fileicon", :name => process[:command]}
339 | m = process[:command].match(/(.*\.app\/).*/)
340 | process[:icon][:name] = m[1] if m
341 |
342 | process[:command] = interpret_command(process)
343 |
344 | # Ignore this script
345 | if process[:command].include?(__FILE__)
346 | next
347 | end
348 |
349 | process[:title] = "#{process[:order]}: #{process[:command]}"
350 |
351 | if @ignored_processes.include?(File.basename(process[:command]))
352 | process[:ignore?] = true
353 | end
354 |
355 | processes[process[:pid]] = process
356 |
357 | process[:subtitle] = "cpu: #{process[:cpu].rjust(6)}%, " \
358 | "memory: #{process[:memory].rjust(6)}%, " \
359 | "nice:#{process[:nice].rjust(4)}, " \
360 | "state:(#{process[:pid].center(8)}) #{process[:state]}"
361 |
362 | i += 1
363 | end
364 | return processes
365 | end
366 |
367 | def interpret_command(process, opts = {})
368 | command = process[:command]
369 | command_basename = File.basename command
370 |
371 | if @vague_commands.include?(command_basename) || opts[:use_command_line]
372 | cmd = %Q{ps -awwwxo 'command' #{process[:pid]}}
373 | ps = Mixlib::ShellOut.new(cmd)
374 | ps.run_command
375 |
376 | if command_line = ps.stdout.lines.map(&:chomp)[1]
377 | if opts[:use_command_line]
378 | return command_line
379 | else
380 | return %Q{#{command_basename}#{command_line.sub(/^#{Regexp.escape(command)}/, '')}}
381 | end
382 | else
383 | return command_basename
384 | end
385 | else
386 | return command_basename
387 | end
388 | end
389 |
390 | def interpret_state(state)
391 | if state.empty?
392 | return ""
393 | end
394 |
395 | m = ""
396 |
397 | states = state.chars.to_a
398 |
399 | m = PS_State[:main][states.shift]
400 | a = []
401 | states.each { |c|
402 | a.push(PS_State[:additional][c])
403 | }
404 |
405 | if a.empty?
406 | return m
407 | else
408 | return "#{m}: #{a.join(',')}"
409 | end
410 | end
411 |
412 | def run_and_message(command, opts = {})
413 | sh = Mixlib::ShellOut.new(command, opts)
414 | sh.run_command
415 | puts status_message(command, sh.exitstatus)
416 | end
417 | end
418 |
419 |
420 |
421 |
422 | if __FILE__ == $PROGRAM_NAME
423 |
424 | Alfred.with_friendly_error do |alfred|
425 | alfred.with_rescue_feedback = true
426 | alfred.with_help_feedback = true
427 |
428 | Top.new(alfred).register
429 | end
430 |
431 |
432 | end
433 |
434 |
435 | # (#
436 | # Modeline ⟨⟨⟨1
437 | # #)
438 | # vim: set ft=ruby ts=2 sw=2 tw=78 fdm=marker fmr=⟨⟨⟨,⟩⟩⟩ fdl=1 :
439 |
--------------------------------------------------------------------------------
/top/bin/AirPodsPower.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # AirPods Battery CLI, Version 2.3
3 | # Contributors: duk242, ankushg, spetykowski, danozdotnet
4 | # Released under the MIT License.
5 |
6 | # The MIT License (MIT)
7 |
8 | # Copyright (c) 2017 Dustin Kerr, and Daniel Jones
9 |
10 | # Permission is hereby granted, free of charge, to any person obtaining a copy
11 | # of this software and associated documentation files (the "Software"), to deal
12 | # in the Software without restriction, including without limitation the rights
13 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | # copies of the Software, and to permit persons to whom the Software is
15 | # furnished to do so, subject to the following conditions:
16 |
17 | # The above copyright notice and this permission notice shall be included in all
18 | # copies or substantial portions of the Software.
19 |
20 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | # SOFTWARE.
27 |
28 | # https://github.com/duk242/AirPodsBatteryCLI
29 |
30 | BLUETOOTH_DEFAULTS=$(defaults read /Library/Preferences/com.apple.Bluetooth); SYSTEM_PROFILER=$(system_profiler SPBluetoothDataType)
31 | MAC_ADDR=$(grep -b2 "Minor Type: Headphones"<<<"${SYSTEM_PROFILER}"|awk '/Address/{print $3}')
32 | CONNECTED=$(grep -ia6 "${MAC_ADDR}"<<<"${SYSTEM_PROFILER}"|awk '/Connected: Yes/{print 1}')
33 | BLUETOOTH_DATA=$(grep -ia6 '"'"${MAC_ADDR}"'"'<<<"${BLUETOOTH_DEFAULTS}")
34 | BATTERY_LEVELS=("BatteryPercentCombined" "HeadsetBattery" "BatteryPercentSingle" "BatteryPercentCase" "BatteryPercentLeft" "BatteryPercentRight")
35 |
36 | if [[ "${CONNECTED}" ]]; then
37 | for I in "${BATTERY_LEVELS[@]}"; do
38 | declare -x "${I}"="$(awk -v pat="${I}" '$0~pat{gsub (";",""); print $3 }'<<<"${BLUETOOTH_DATA}")"
39 | [[ ! -z "${!I}" ]] && OUTPUT="${OUTPUT} $(awk '/BatteryPercent/{print substr($0,15,1)": "}'<<<"${I}")${!I}%"
40 | done
41 | printf "%s\\n" "${OUTPUT}"
42 | else
43 | printf "%s Not Connected\\n" "${OUTPUT}"
44 | fi
--------------------------------------------------------------------------------
/top/bin/fans_tempsMonitor:
--------------------------------------------------------------------------------
1 | /Users/zhaocai/Software/Theme/GeekTool/fans_tempsMonitor
--------------------------------------------------------------------------------
/top/bin/iosnoop.d:
--------------------------------------------------------------------------------
1 | #!/usr/sbin/dtrace -s
2 |
3 |
4 | #pragma D option quiet
5 | #pragma D option switchrate=10hz
6 |
7 | /*
8 | * Init Variables
9 | */
10 | dtrace:::BEGIN
11 | {
12 | last_event[""] = 0;
13 | }
14 |
15 |
16 | /*
17 | * Reset last_event for disk idle -> start
18 | * this prevents idle time being counted as disk time.
19 | */
20 | io:::start
21 | /! pending[args[1]->dev_statname]/
22 | {
23 | /* save last disk event */
24 | last_event[args[1]->dev_statname] = timestamp;
25 | }
26 |
27 | /*
28 | * Store entry details
29 | */
30 | io:::start
31 | {
32 | /* these are used as a unique disk event key, */
33 | this->dev = args[0]->b_edev;
34 | this->blk = args[0]->b_blkno;
35 |
36 | /* save disk event details, */
37 | start_uid[this->dev, this->blk] = (int)uid;
38 | start_pid[this->dev, this->blk] = pid;
39 | start_ppid[this->dev, this->blk] = ppid;
40 | start_args[this->dev, this->blk] = (char *)curpsinfo->pr_psargs;
41 | start_comm[this->dev, this->blk] = execname;
42 | start_time[this->dev, this->blk] = timestamp;
43 |
44 | /* increase disk event pending count */
45 | pending[args[1]->dev_statname]++;
46 | }
47 |
48 | /*
49 | * Process and Print completion
50 | */
51 | io:::done
52 | /start_time[args[0]->b_edev, args[0]->b_blkno]/
53 | {
54 | /* decrease disk event pending count */
55 | pending[args[1]->dev_statname]--;
56 |
57 | /*
58 | * Process details
59 | */
60 |
61 | /* fetch entry values */
62 | this->dev = args[0]->b_edev;
63 | this->blk = args[0]->b_blkno;
64 | this->suid = start_uid[this->dev, this->blk];
65 | this->spid = start_pid[this->dev, this->blk];
66 | this->sppid = start_ppid[this->dev, this->blk];
67 | self->sargs = (int)start_args[this->dev, this->blk] == 0 ?
68 | "" : start_args[this->dev, this->blk];
69 | self->scomm = start_comm[this->dev, this->blk];
70 | this->stime = start_time[this->dev, this->blk];
71 | this->etime = timestamp; /* endtime */
72 | this->delta = this->etime - this->stime;
73 | this->dtime = last_event[args[1]->dev_statname] == 0 ? 0 :
74 | timestamp - last_event[args[1]->dev_statname];
75 |
76 | /* memory cleanup */
77 | start_uid[this->dev, this->blk] = 0;
78 | start_pid[this->dev, this->blk] = 0;
79 | start_ppid[this->dev, this->blk] = 0;
80 | start_args[this->dev, this->blk] = 0;
81 | start_time[this->dev, this->blk] = 0;
82 | start_comm[this->dev, this->blk] = 0;
83 | start_rw[this->dev, this->blk] = 0;
84 |
85 | /*
86 | * Print details
87 | */
88 |
89 | printf("%d ⟩ %s ⟩ %d ⟩ %s ⟩ %s ⟩ %s ⟩ %s ⟩ %s\n",
90 | this->spid,
91 | args[0]->b_flags & B_READ ? "R" : "W",
92 | args[0]->b_bcount,
93 | self->scomm,
94 | self->sargs,
95 | args[1]->dev_pathname,
96 | args[2]->fi_mount,
97 | args[2]->fi_pathname
98 | );
99 |
100 | /* save last disk event */
101 | last_event[args[1]->dev_statname] = timestamp;
102 |
103 | /* cleanup */
104 | self->scomm = 0;
105 | self->sargs = 0;
106 | }
107 |
108 | /*
109 | * Prevent pending from underflowing
110 | * this can happen if this program is started during disk events.
111 | */
112 | io:::done
113 | /pending[args[1]->dev_statname] < 0/
114 | {
115 | pending[args[1]->dev_statname] = 0;
116 | }
117 |
118 |
119 |
120 | /*
121 | * vim:ft=dtrace:ts=8:sw=4:tw=4:fmr=⟨⟨⟨,⟩⟩⟩:fdm=syntax:
122 | */
123 |
--------------------------------------------------------------------------------
/top/bin/smc:
--------------------------------------------------------------------------------
1 | /usr/local/bin/smc
--------------------------------------------------------------------------------
/top/glance.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # -*- coding: utf-8 -*-
3 | ($LOAD_PATH << File.expand_path("..", __FILE__)).uniq!
4 |
5 | require 'rubygems' unless defined? Gem # rubygems is only needed in 1.8
6 |
7 | require "bundle/bundler/setup"
8 | require "alfred"
9 | require 'plist'
10 | require 'yaml'
11 | require 'mixlib/shellout'
12 | require 'iStats'
13 |
14 | class Glance
15 | SMC_KEYS = {
16 | 'TC0P' => 'cpu_temperature',
17 | 'TG0P' => 'gpu_temperature',
18 | 'F0Ac' => 'fan0_speed',
19 | 'F1Ac' => 'fan1_speed',
20 | }
21 |
22 | def self.sh(command, opts = {})
23 | shell = Mixlib::ShellOut.new(command)
24 | shell.run_command
25 | shell.error!
26 | return shell
27 | end
28 |
29 | def self.with_query(query)
30 | if query[1].eql? '⟩'
31 | return query[2..-1]
32 | else
33 | return query
34 | end
35 | end
36 |
37 | def initialize(alfred, query)
38 | @alfred = alfred
39 | @feedback = @alfred.feedback
40 | if query[1].eql? '⟩'
41 | @actor = query[0].downcase
42 | end
43 | end
44 |
45 |
46 | def collect
47 | collect_battery
48 | collect_temperature
49 | collect_bluetooth
50 | collect_storage
51 | end
52 |
53 |
54 | def collect_temperature
55 | return if @actor
56 |
57 | # temp = IStats::Cpu.delegate("all")
58 |
59 | # > IStats.get_info[:cpu_temperature]
60 | # => {:battery_health_stats=>{:battery_health=>"Good", :max_design_cycle_count=>1000, :cycle_count=>"156", :cycle_count_percentage=>15.6, :thresholds=>[450.0, 650.0, 850.0, 950.0], :battery_temp=>31.796875}, :battery_charge_stats=>{:cur_charge=>"3630", :cur_charge_percentage=>64, :original_max_capacity=>6559.0, :current_max_capacity=>5932.0}, :cpu_temperature=>43.5, :cpu_thresholds=>[50, 68, 80, 90], :fan_numbers_and_speeds=>[[1, 0]]}
61 |
62 | cpu_temperature = IStats.get_info[:cpu_temperature]
63 | icon = {:type => "default", :name => "icon/temperature/GPU.png"}
64 | @feedback.add_item(
65 | :subtitle => "CPU: #{cpu_temperature}° C" ,
66 | :title => "CPU Temperature" ,
67 | :uid => "CPU Temperature" ,
68 | :icon => icon)
69 |
70 | # gpu_temperature = 200
71 | # icon = {:type => "default", :name => "icon/temperature/GPU.png"}
72 | # @feedback.add_item(
73 | # :subtitle => "GPU: #{gpu_temperature}° C" ,
74 | # :title => "GPU Temperature" ,
75 | # :uid => "GPU Temperature" ,
76 | # :icon => icon)
77 |
78 | # [number, speed]
79 | IStats.get_info[:fan_numbers_and_speeds].each{|info_arr|
80 | add_fan_speed_item(info_arr)
81 | }
82 | end
83 |
84 | def add_fan_speed_item(info_arr)
85 | fan_number = info_arr[0]
86 | fan_speed = info_arr[1]
87 | if fan_speed < 3500
88 | icon = {:type => "default", :name => "icon/fan/green.png"}
89 | title = "Fan Speed: Normal"
90 | elsif fan_speed < 5500
91 | icon = {:type => "default", :name => "icon/fan/blue.png"}
92 | title = "Fan Speed: Fast"
93 | else
94 | icon = {:type => "default", :name => "icon/fan/red.png"}
95 | title = "Fan Speed: Driving Crazy!"
96 | end
97 | @feedback.add_item(
98 | :subtitle => "Fan #{fan_number}: #{fan_speed} RPM" ,
99 | :uid => "Fan #{fan_number} Speed",
100 | :title => title,
101 | :icon => icon)
102 |
103 | end
104 |
105 | def collect_storage
106 | return if @actor
107 |
108 | devices = %x{/bin/df -H}.split("\n")
109 |
110 | devices.each do |device|
111 | next unless device.start_with? '/dev/'
112 |
113 | items = device.split
114 | size = items[1]
115 | used = items[2]
116 | free = items[3]
117 | percent = items[4][0...-1].to_i
118 | mount_point = items[8..-1].join(" ")
119 | if mount_point.eql? '/'
120 | name = 'Root'
121 | else
122 | name = File.basename(mount_point)
123 | end
124 | @feedback.add_file_item(mount_point,
125 | :title => "#{name}: #{free} free",
126 | :subtitle =>"#{percent}%, #{used} used of #{size} total")
127 | end
128 | end
129 |
130 |
131 | def collect_bluetooth
132 | return if @actor
133 |
134 | bluetooth_device_keys = ["BNBMouseDevice", "AppleBluetoothHIDKeyboard", "BNBTrackpadDevice"]
135 |
136 | bluetooth_device_keys.each do |key|
137 | devices = Plist.parse_xml %x{ioreg -l -n #{key} -r -a}
138 | next if devices.nil? || devices.empty?
139 |
140 | devices.each do |device|
141 | name = device["Product"]
142 | serial = device["SerialNumber"]
143 | percent = device["BatteryPercent"].to_i
144 | icon = {:type => "default", :name => "icon/bluetooth/#{key}.png"}
145 | @feedback.add_item(:subtitle => "#{percentage_sign(percent)} #{percent}%",
146 | :title => "#{name}",
147 | :uid => "#{key}: #{serial}",
148 | :icon => icon)
149 | end
150 | end
151 |
152 | end
153 |
154 | def collect_battery
155 | if @actor.eql? "battery"
156 | show_detailed_feedback = true
157 | else
158 | if @actor
159 | return
160 | else
161 | show_detailed_feedback = false
162 | end
163 | end
164 |
165 |
166 | devices = Plist.parse_xml %x{ioreg -l -n AppleSmartBattery -r -a}
167 | return if devices.nil? || devices.empty?
168 |
169 | devices.each do |device|
170 | current_capacity = device["CurrentCapacity"]
171 | max_capacity = device["MaxCapacity"]
172 | design_capacity = device['DesignCapacity']
173 | temperature = device['Temperature'].to_f / 100
174 | is_charging = device['IsCharging']
175 | serial = device['BatterySerialNumber']
176 | cycle_count = device['CycleCount']
177 | fully_charged = device['FullyCharged']
178 | is_external = device['ExternalConnected']
179 | time_to_full = device['AvgTimeToFull']
180 | time_to_empty = device['AvgTimeToEmpty']
181 | manufacture_date = device['ManufactureDate']
182 |
183 |
184 | day = manufacture_date & 31
185 | month = (manufacture_date >> 5 ) & 15
186 | year = 1980 + (manufacture_date >> 9)
187 |
188 | manufacture_date = Date.new(year, month, day)
189 | # month as unit
190 | age = (Date.today - manufacture_date).to_f / 30
191 |
192 | health = max_capacity * 100 / design_capacity
193 | percent = current_capacity * 100 / max_capacity
194 |
195 |
196 | if percent > 80
197 | icon_name = 'full'
198 | elsif percent > 50
199 | icon_name = 'medium'
200 | elsif percent > 10
201 | icon_name = 'low'
202 | else
203 | icon_name = 'critical'
204 | end
205 |
206 | time_info = 'Charging'
207 |
208 | if is_charging
209 | if time_to_full == 65535
210 | time_info = 'Calculating...'
211 | else
212 | time_info = "#{time_to_full} min until Full"
213 | end
214 | else
215 | if fully_charged
216 | if is_external
217 | time_info = 'On AC Power'
218 | icon_name = 'power'
219 | else
220 | time_info = "#{time_to_empty} min Left"
221 | end
222 | else
223 | time_info = "#{time_to_empty} min Left"
224 | end
225 | end
226 |
227 | if is_charging
228 | status_info = "Charging"
229 | elsif fully_charged
230 | status_info = 'Fully Charged'
231 | else
232 | status_info = "Draining"
233 | end
234 |
235 | icon = {:type => "default", :name => "icon/battery/#{icon_name}.png"}
236 |
237 | battery_item = {
238 | :title => "#{status_info}, #{time_info}" ,
239 | :subtitle => "#{percentage_sign(percent)} #{percent}%" ,
240 | :uid => "Battery: #{serial}" ,
241 | :valid => 'no' ,
242 | :autocomplete => 'Battery ⟩ ' ,
243 | :icon => icon ,
244 | }
245 |
246 | if show_detailed_feedback
247 | battery_item[:valid] = 'yes'
248 | battery_item[:title] = status_info
249 |
250 | @feedback.add_item(battery_item)
251 |
252 | @feedback.add_item(
253 | :title => "#{time_info}",
254 | :subtitle => 'Time',
255 | :icon => {:type => "default", :name => "icon/battery/clock.png"}
256 | )
257 | @feedback.add_item(
258 | :title => "#{temperature}° C",
259 | :subtitle => 'Temperature',
260 | :icon => {:type => "default", :name => "icon/battery/temp.png"}
261 | )
262 | @feedback.add_item(
263 | :title => "#{cycle_count} Cycles",
264 | :subtitle => 'Charge Cycles',
265 | :icon => {:type => "default", :name => "icon/battery/cycles.png"}
266 | )
267 | @feedback.add_item(
268 | :title => "#{health}%",
269 | :subtitle => 'Health',
270 | :icon => {:type => "default", :name => "icon/battery/health.png"}
271 | )
272 | @feedback.add_item(
273 | :title => "#{serial}",
274 | :subtitle => 'Serial Number',
275 | :match? => :all_title_match?,
276 | :icon => {:type => "default", :name => "icon/battery/serial.png"}
277 | )
278 | @feedback.add_item(
279 | :title => "#{age.round} months",
280 | :subtitle => 'Age',
281 | :icon => {:type => "default", :name => "icon/battery/age.png"}
282 | )
283 | else
284 | airpods_battery()
285 | @feedback.add_item(battery_item)
286 | end
287 | end
288 |
289 | end
290 |
291 | private
292 |
293 | def airpods_battery
294 | battery_info_raw = %x{bash ./bin/AirPodsPower.sh}
295 | return if battery_info_raw.include?("Not Connected")
296 |
297 | icon = {:type => "default", :name => "icon/battery/airpods-3.png"}
298 | battery_info = battery_info_raw
299 | .strip
300 | .gsub(" ", "")
301 | .split("%")
302 | .select{|el|
303 | el.split(":")[1] != "0"
304 | }
305 | .map{|el| el+"%"}.join(", ")
306 | .gsub("L:", "Left :")
307 | .gsub("R:", "Right :")
308 | .gsub("C:", "Case :")
309 |
310 | airpods_battery_item = {
311 | :title => "Airpods" ,
312 | :subtitle => "#{battery_info}" ,
313 | :uid => "Airpods" ,
314 | :valid => 'no' ,
315 | :autocomplete => 'Airpods ⟩ ' ,
316 | :icon => icon ,
317 | }
318 | @feedback.add_item(airpods_battery_item)
319 | end
320 |
321 | def percentage_sign(percent, use_sign = :emoji)
322 | if use_sign.eql? :emoji
323 | full = '🔴'
324 | empty = '⚪'
325 | elsif use_sign.eql? :plain
326 | full = '●'
327 | empty = '○'
328 | elsif use_sign.eql? :fruit
329 | signs = ["🍎", "🍎", "🍎", "🍊", "🍊", "🍊", "🍏" , "🍏", "🍏", "🍏", "🍏"]
330 | mark = percent / 10
331 | return signs[0...mark].join
332 | end
333 | mark = percent / 10
334 | sign = ''
335 | mark.times { |_| sign += full }
336 | (10 - mark).times { |_| sign += empty }
337 | sign
338 | end
339 |
340 | end
341 | def generate_feedback(alfred, query)
342 | eye = Glance.new(alfred, query)
343 | eye.collect
344 |
345 | puts alfred.feedback.to_alfred(Glance.with_query(query))
346 | end
347 |
348 |
349 | if __FILE__ == $PROGRAM_NAME
350 | Alfred.with_friendly_error do |alfred|
351 | alfred.with_rescue_feedback = true
352 | generate_feedback(alfred, ARGV)
353 | end
354 | end
355 |
--------------------------------------------------------------------------------
/top/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon.png
--------------------------------------------------------------------------------
/top/icon/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/.DS_Store
--------------------------------------------------------------------------------
/top/icon/battery/age.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/age.png
--------------------------------------------------------------------------------
/top/icon/battery/airpods-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/airpods-2.png
--------------------------------------------------------------------------------
/top/icon/battery/airpods-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/airpods-3.png
--------------------------------------------------------------------------------
/top/icon/battery/airpods.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/airpods.png
--------------------------------------------------------------------------------
/top/icon/battery/charging.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/charging.png
--------------------------------------------------------------------------------
/top/icon/battery/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/clock.png
--------------------------------------------------------------------------------
/top/icon/battery/critical.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/critical.png
--------------------------------------------------------------------------------
/top/icon/battery/cycles.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/cycles.png
--------------------------------------------------------------------------------
/top/icon/battery/full.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/full.png
--------------------------------------------------------------------------------
/top/icon/battery/health.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/health.png
--------------------------------------------------------------------------------
/top/icon/battery/low.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/low.png
--------------------------------------------------------------------------------
/top/icon/battery/medium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/medium.png
--------------------------------------------------------------------------------
/top/icon/battery/power.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/power.png
--------------------------------------------------------------------------------
/top/icon/battery/serial.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/serial.png
--------------------------------------------------------------------------------
/top/icon/battery/temp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/battery/temp.png
--------------------------------------------------------------------------------
/top/icon/bluetooth/AppleBluetoothHIDKeyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/bluetooth/AppleBluetoothHIDKeyboard.png
--------------------------------------------------------------------------------
/top/icon/bluetooth/BNBMouseDevice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/bluetooth/BNBMouseDevice.png
--------------------------------------------------------------------------------
/top/icon/bluetooth/BNBTrackpadDevice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/bluetooth/BNBTrackpadDevice.png
--------------------------------------------------------------------------------
/top/icon/fan/blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/fan/blue.png
--------------------------------------------------------------------------------
/top/icon/fan/green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/fan/green.png
--------------------------------------------------------------------------------
/top/icon/fan/red.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/fan/red.png
--------------------------------------------------------------------------------
/top/icon/process/GPU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/process/GPU.png
--------------------------------------------------------------------------------
/top/icon/process/auto.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/process/auto.png
--------------------------------------------------------------------------------
/top/icon/process/cpu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/process/cpu.png
--------------------------------------------------------------------------------
/top/icon/process/io.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/process/io.png
--------------------------------------------------------------------------------
/top/icon/process/memory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/process/memory.png
--------------------------------------------------------------------------------
/top/icon/temperature/GPU.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/singhprd/system-monitor-alfred-workflow/f2a9def95f864743cc5b9bd03a218ba62f5c52a4/top/icon/temperature/GPU.png
--------------------------------------------------------------------------------
/top/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bundleid
6 | me.zhaowu.top
7 | connections
8 |
9 | 2011A968-7743-480E-A078-3D3602FF8E11
10 |
11 |
12 | destinationuid
13 | C439BF3F-F4EF-43E6-BFD2-DF8837E2B120
14 | modifiers
15 | 0
16 | modifiersubtext
17 |
18 |
19 |
20 | 2B8AA7B1-2F79-475C-ADEF-6EE35005FCBA
21 |
22 |
23 | destinationuid
24 | CFA5D2DB-0DDA-4D3C-9755-3C4DD3A6BA29
25 | modifiers
26 | 0
27 | modifiersubtext
28 |
29 |
30 |
31 | 6DED0FCD-B485-4D7D-A4B7-673C0D34E2D0
32 |
33 |
34 | destinationuid
35 | CA714745-B63F-46C5-9D77-50C52956368C
36 | modifiers
37 | 0
38 | modifiersubtext
39 |
40 |
41 |
42 | 7DC8A847-D1E3-4D91-B2B5-844E95E7F38A
43 |
44 |
45 | destinationuid
46 | A162DE22-9392-4CD1-AA9C-AAC39F6D31F8
47 | modifiers
48 | 0
49 | modifiersubtext
50 |
51 |
52 |
53 | destinationuid
54 | DA167D3F-4147-4632-A672-72656D18E997
55 | modifiers
56 | 1048576
57 | modifiersubtext
58 | Force Kill
59 |
60 |
61 | A162DE22-9392-4CD1-AA9C-AAC39F6D31F8
62 |
63 |
64 | destinationuid
65 | 4F27382C-82E2-4594-91A4-A671F119A335
66 | modifiers
67 | 0
68 | modifiersubtext
69 |
70 |
71 |
72 | CA714745-B63F-46C5-9D77-50C52956368C
73 |
74 |
75 | destinationuid
76 | CE16D203-D372-4FC5-AA16-B8A41ECA3D16
77 | modifiers
78 | 524288
79 | modifiersubtext
80 | nice cpu priority
81 |
82 |
83 | destinationuid
84 | A493B0AC-FD4E-459A-9CFE-2137F39C6249
85 | modifiers
86 | 131072
87 | modifiersubtext
88 | Search for process info online
89 |
90 |
91 | destinationuid
92 | A162DE22-9392-4CD1-AA9C-AAC39F6D31F8
93 | modifiers
94 | 262144
95 | modifiersubtext
96 | kill process
97 |
98 |
99 | destinationuid
100 | 3F4FBD02-B2C3-467A-9976-05BF7556923E
101 | modifiers
102 | 0
103 | modifiersubtext
104 |
105 |
106 |
107 | destinationuid
108 | DA167D3F-4147-4632-A672-72656D18E997
109 | modifiers
110 | 1048576
111 | modifiersubtext
112 | force kill
113 |
114 |
115 | CE16D203-D372-4FC5-AA16-B8A41ECA3D16
116 |
117 |
118 | destinationuid
119 | 638845CE-0394-46AA-85F6-723639C71696
120 | modifiers
121 | 0
122 | modifiersubtext
123 |
124 |
125 |
126 | DA167D3F-4147-4632-A672-72656D18E997
127 |
128 |
129 | destinationuid
130 | 4F27382C-82E2-4594-91A4-A671F119A335
131 | modifiers
132 | 0
133 | modifiersubtext
134 |
135 |
136 |
137 |
138 | createdby
139 | Zhao Cai
140 | description
141 | List/Kill Top Processes by Memory, Cpu or IO Usage
142 | disabled
143 |
144 | name
145 | Top Processes
146 | objects
147 |
148 |
149 | config
150 |
151 | lastpathcomponent
152 |
153 | onlyshowifquerypopulated
154 |
155 | output
156 | 0
157 | removeextension
158 |
159 | sticky
160 |
161 | text
162 | {query}
163 | title
164 | nice cpu priority
165 |
166 | type
167 | alfred.workflow.output.notification
168 | uid
169 | 638845CE-0394-46AA-85F6-723639C71696
170 | version
171 | 0
172 |
173 |
174 | config
175 |
176 | escaping
177 | 38
178 | script
179 | LANG=en_US.UTF-8 /usr/bin/ruby ./alfred2_top_workflow.rb --workflow-mode=action --modifier=alt "{query}"
180 | type
181 | 0
182 |
183 | type
184 | alfred.workflow.action.script
185 | uid
186 | CE16D203-D372-4FC5-AA16-B8A41ECA3D16
187 | version
188 | 0
189 |
190 |
191 | config
192 |
193 | argumenttype
194 | 1
195 | escaping
196 | 36
197 | keyword
198 | kill
199 | runningsubtext
200 | list processes...
201 | script
202 | LANG=en_US.UTF-8 /usr/bin/ruby ./alfred2_top_workflow.rb {query}
203 | subtext
204 | Type to filter processes
205 | title
206 | Kill Process
207 | type
208 | 0
209 | withspace
210 |
211 |
212 | type
213 | alfred.workflow.input.scriptfilter
214 | uid
215 | 7DC8A847-D1E3-4D91-B2B5-844E95E7F38A
216 | version
217 | 0
218 |
219 |
220 | config
221 |
222 | escaping
223 | 38
224 | script
225 | LANG=en_US.UTF-8 /usr/bin/ruby ./alfred2_top_workflow.rb --workflow-mode=action --modifier=shift "{query}"
226 | type
227 | 0
228 |
229 | type
230 | alfred.workflow.action.script
231 | uid
232 | A493B0AC-FD4E-459A-9CFE-2137F39C6249
233 | version
234 | 0
235 |
236 |
237 | config
238 |
239 | escaping
240 | 38
241 | script
242 | LANG=en_US.UTF-8 /usr/bin/ruby ./alfred2_top_workflow.rb --workflow-mode=action --modifier=control "{query}"
243 | type
244 | 0
245 |
246 | type
247 | alfred.workflow.action.script
248 | uid
249 | A162DE22-9392-4CD1-AA9C-AAC39F6D31F8
250 | version
251 | 0
252 |
253 |
254 | config
255 |
256 | lastpathcomponent
257 |
258 | onlyshowifquerypopulated
259 |
260 | output
261 | 0
262 | removeextension
263 |
264 | sticky
265 |
266 | text
267 | {query}
268 | title
269 | Kill Process
270 |
271 | type
272 | alfred.workflow.output.notification
273 | uid
274 | 4F27382C-82E2-4594-91A4-A671F119A335
275 | version
276 | 0
277 |
278 |
279 | config
280 |
281 | action
282 | 0
283 | argument
284 | 0
285 | hotkey
286 | 0
287 | hotmod
288 | 0
289 | hotstring
290 |
291 | leftcursor
292 |
293 | modsmode
294 | 0
295 |
296 | type
297 | alfred.workflow.trigger.hotkey
298 | uid
299 | 6DED0FCD-B485-4D7D-A4B7-673C0D34E2D0
300 | version
301 | 0
302 |
303 |
304 | config
305 |
306 | escaping
307 | 102
308 | script
309 | LANG=en_US.UTF-8 /usr/bin/ruby ./alfred2_top_workflow.rb --workflow-mode=action "{query}"
310 | type
311 | 0
312 |
313 | type
314 | alfred.workflow.action.script
315 | uid
316 | 3F4FBD02-B2C3-467A-9976-05BF7556923E
317 | version
318 | 0
319 |
320 |
321 | config
322 |
323 | argumenttype
324 | 1
325 | escaping
326 | 0
327 | keyword
328 | top
329 | runningsubtext
330 | Determining top processes...
331 | script
332 | LANG=en_US.UTF-8 /usr/bin/ruby ./alfred2_top_workflow.rb {query}
333 | subtext
334 | sort by Memory, CPU, or IO usage
335 | title
336 | Search Top Processes for '{query}'
337 | type
338 | 0
339 | withspace
340 |
341 |
342 | type
343 | alfred.workflow.input.scriptfilter
344 | uid
345 | CA714745-B63F-46C5-9D77-50C52956368C
346 | version
347 | 0
348 |
349 |
350 | config
351 |
352 | escaping
353 | 38
354 | script
355 | LANG=en_US.UTF-8 /usr/bin/ruby ./alfred2_top_workflow.rb --workflow-mode=action --modifier=command "{query}"
356 | type
357 | 0
358 |
359 | type
360 | alfred.workflow.action.script
361 | uid
362 | DA167D3F-4147-4632-A672-72656D18E997
363 | version
364 | 0
365 |
366 |
367 | config
368 |
369 | argumenttype
370 | 0
371 | escaping
372 | 62
373 | keyword
374 | lsof
375 | runningsubtext
376 | waiting...
377 | script
378 | LANG=en_US.UTF-8 /usr/bin/ruby ./lsof.rb {query}
379 | subtext
380 | lsof pid query
381 | title
382 | List Files Opened by Process {query}
383 | type
384 | 0
385 | withspace
386 |
387 |
388 | type
389 | alfred.workflow.input.scriptfilter
390 | uid
391 | 2B8AA7B1-2F79-475C-ADEF-6EE35005FCBA
392 | version
393 | 0
394 |
395 |
396 | type
397 | alfred.workflow.action.revealfile
398 | uid
399 | CFA5D2DB-0DDA-4D3C-9755-3C4DD3A6BA29
400 | version
401 | 0
402 |
403 |
404 | config
405 |
406 | argumenttype
407 | 1
408 | escaping
409 | 0
410 | keyword
411 | glance
412 | runningsubtext
413 | working on it ヽ( ´¬`)ノ
414 | script
415 | LANG=en_US.UTF-8 /usr/bin/ruby ./glance.rb {query}
416 | subtext
417 | Type '{query}' to filter
418 | title
419 | Glances an Eye on your system
420 | type
421 | 0
422 | withspace
423 |
424 |
425 | type
426 | alfred.workflow.input.scriptfilter
427 | uid
428 | C439BF3F-F4EF-43E6-BFD2-DF8837E2B120
429 | version
430 | 0
431 |
432 |
433 | config
434 |
435 | action
436 | 0
437 | argument
438 | 0
439 | hotkey
440 | 0
441 | hotmod
442 | 0
443 | hotstring
444 |
445 | leftcursor
446 |
447 | modsmode
448 | 0
449 |
450 | type
451 | alfred.workflow.trigger.hotkey
452 | uid
453 | 2011A968-7743-480E-A078-3D3602FF8E11
454 | version
455 | 0
456 |
457 |
458 | config
459 |
460 | applescript
461 | on alfred_script(q)
tell application "Alfred 2" to search "lsof " & q & " "
end alfred_script
462 |
463 | cachescript
464 |
465 |
466 | type
467 | alfred.workflow.action.applescript
468 | uid
469 | A325DFB8-2F81-4919-8541-1365154D5F89
470 | version
471 | 0
472 |
473 |
474 | readme
475 | Lists top ten system processes by CPU or Memory usage. Provide actions to kill.
476 | uidata
477 |
478 | 2011A968-7743-480E-A078-3D3602FF8E11
479 |
480 | ypos
481 | 690
482 |
483 | 2B8AA7B1-2F79-475C-ADEF-6EE35005FCBA
484 |
485 | ypos
486 | 520
487 |
488 | 3F4FBD02-B2C3-467A-9976-05BF7556923E
489 |
490 | ypos
491 | 330
492 |
493 | 4F27382C-82E2-4594-91A4-A671F119A335
494 |
495 | ypos
496 | 270
497 |
498 | 638845CE-0394-46AA-85F6-723639C71696
499 |
500 | ypos
501 | 10
502 |
503 | 6DED0FCD-B485-4D7D-A4B7-673C0D34E2D0
504 |
505 | ypos
506 | 320
507 |
508 | 7DC8A847-D1E3-4D91-B2B5-844E95E7F38A
509 |
510 | ypos
511 | 120
512 |
513 | A162DE22-9392-4CD1-AA9C-AAC39F6D31F8
514 |
515 | ypos
516 | 230
517 |
518 | A325DFB8-2F81-4919-8541-1365154D5F89
519 |
520 | ypos
521 | 1010
522 |
523 | A493B0AC-FD4E-459A-9CFE-2137F39C6249
524 |
525 | ypos
526 | 130
527 |
528 | C439BF3F-F4EF-43E6-BFD2-DF8837E2B120
529 |
530 | ypos
531 | 670
532 |
533 | CA714745-B63F-46C5-9D77-50C52956368C
534 |
535 | ypos
536 | 340
537 |
538 | CE16D203-D372-4FC5-AA16-B8A41ECA3D16
539 |
540 | ypos
541 | 30
542 |
543 | CFA5D2DB-0DDA-4D3C-9755-3C4DD3A6BA29
544 |
545 | ypos
546 | 590
547 |
548 | DA167D3F-4147-4632-A672-72656D18E997
549 |
550 | ypos
551 | 460
552 |
553 |
554 | webaddress
555 | https://github.com/zhaocai/alfred2-top-workflow
556 |
557 |
558 |
--------------------------------------------------------------------------------
/top/lsof.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # -*- coding: utf-8 -*-
3 | # ============== = ===========================================================
4 | # Description : Alfred 2 Top Processes Workflow
5 | # Author : Zhao Cai
6 | # HomePage : https://github.com/zhaocai/alfred2-top-workflow
7 | # Version : 0.1
8 | # Date Created : Sun 10 Mar 2013 09:59:48 PM EDT
9 | # Last Modified : Sat 30 Mar 2013 10:48:07 PM EDT
10 | # Tag : [ ruby, alfred, workflow ]
11 | # Copyright : © 2013 by Zhao Cai,
12 | # Released under current GPL license.
13 | # ============== = ===========================================================
14 |
15 | ($LOAD_PATH << File.expand_path("..", __FILE__)).uniq!
16 |
17 | require 'rubygems' unless defined? Gem # rubygems is only needed in 1.8
18 | require "bundle/bundler/setup"
19 | require "alfred"
20 | require 'open3'
21 |
22 |
23 | # OPTIMIZE: use pgrep for name based search
24 | def valid_pid?(pid)
25 | return false if pid.nil?
26 | !pid.match(/[^0-9]/)
27 | end
28 |
29 | def generate_feedback(alfred, pid, with_query)
30 | fb = alfred.feedback
31 |
32 | files = []
33 |
34 | c = %Q{lsof -p #{pid}}
35 | stdin, stdout, stderr = Open3.popen3(c)
36 | lines = stdout.readlines.map(&:chomp)
37 |
38 | if lines.empty?
39 | # try sudo
40 | c = %Q{./sudo.sh #{c}}
41 | stdin, stdout, stderr = Open3.popen3(c)
42 | lines = stdout.readlines.map(&:chomp)
43 | end
44 |
45 | if lines.empty?
46 | puts alfred.rescue_feedback(:title => "Is #{pid} a valid PID? Or the process has been terminated.")
47 | return false
48 | end
49 |
50 | lines.shift
51 |
52 | lines.each do |entry|
53 | columns = entry.split
54 | f = columns[8..-1]
55 | if f
56 | file = f.join(" ")
57 | files << file if File.exist?(file)
58 | end
59 | end
60 |
61 | files.delete_if { |f|
62 | f.start_with?("/Applications/") or f.eql?('/') or f.eql?('/dev/null')
63 | }
64 |
65 |
66 | files.each do |f|
67 | fb.add_file_item(f)
68 | end
69 |
70 | puts fb.to_alfred(with_query)
71 | end
72 |
73 | if __FILE__ == $PROGRAM_NAME
74 | Alfred.with_friendly_error do |alfred|
75 |
76 | alfred.with_rescue_feedback = true
77 |
78 | pid = ARGV[0]
79 | ARGV.shift
80 |
81 | unless valid_pid?(pid)
82 | puts alfred.rescue_feedback(:title => "Invalid PID: #{pid}")
83 | exit(-1)
84 | end
85 |
86 | generate_feedback(alfred, pid, ARGV)
87 | end
88 | end
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/top/setting.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | :id: me.zhaowu.top
3 | :Homepage : &homepage
4 | http://zhaocai.github.io/alfred2-top-workflow/
5 | :triviaware : &triviaware
6 | http://triviaware.com/macprocess/all
7 | :macinside : &macinside
8 | http://www.macinside.info/
9 | :help:
10 | - :kind: url
11 | :title: Homepage
12 | :subtitle: *homepage
13 | :url: *homepage
14 | - :kind: url
15 | :title: MacInside - Apple Mac Process & Security Information
16 | :subtitle: *macinside
17 | :order: 300
18 | :url: *macinside
19 | - :kind: url
20 | :order: 301
21 | :title: Know your Mac OS X processes - Information about your Mac system processes and applications
22 | :subtitle: *triviaware
23 | :url: *triviaware
24 | - :kind: file
25 | :path: README.pdf
26 |
27 |
--------------------------------------------------------------------------------
/top/sudo.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env zsh
2 | PASS=$(Authenticate.app/Contents/MacOS/Authenticate -get password)
3 | if [ "$PASS" = "(null)" ] ; then
4 | Authenticate.app/Contents/MacOS/Authenticate
5 | PASS=$(Authenticate.app/Contents/MacOS/Authenticate -get password)
6 | fi
7 | echo $PASS | sudo -S "$@"
8 |
9 |
--------------------------------------------------------------------------------
/top/top:
--------------------------------------------------------------------------------
1 | /Users/peter/Dev/alfred2-top-workflow/top
--------------------------------------------------------------------------------
/top/update.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2.0,
3 | "remote_json": "https://github.com/zhaocai/alfred2-top-workflow/raw/master/version.json"
4 | }
5 |
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2.0,
3 | "download_uri": "https://github.com/zhaocai/alfred2-top-workflow/raw/master/Top%20Processes.alfredworkflow",
4 | "description": "flexible handler framework"
5 | }
6 |
--------------------------------------------------------------------------------