hardstatus 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +116 -0
- data/Rakefile +5 -0
- data/bin/hardstatus-daemon +17 -0
- data/ext/hardstatus.c +51 -0
- data/hardstatus.gemspec +17 -0
- data/lib/hardstatus.rb +93 -0
- data/lib/hardstatus/controller.rb +33 -0
- data/lib/hardstatus/time.rb +61 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 573b9cf310275c4edd2fc8e5f68ac1f3e1bb96d7
|
4
|
+
data.tar.gz: 7a6bc21f0b9b9b3e93b4b6e16ce72bdfd5484c73
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73706e6604dd64f6e9b9771d54ff511d3995c4014ca360edd1227f96e873c9bcba54fa3d1016f48c851ade6abf12a53caebce7ca5b229f562550475b0b19e333
|
7
|
+
data.tar.gz: 3f43737450231c0c0504f9e6578ad360f86a5915c0626fb9f2e1ecd2d20a19e79db97b2df16527aba34a30c5789e7fe530193588c307eef1f894e4b0ec3592f7
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
hardstatus
|
2
|
+
==========
|
3
|
+
I use the GNU screen hardstatus as global status bar, the downside was I had
|
4
|
+
about 10 scripts that would make the whole thing lag every few seconds.
|
5
|
+
|
6
|
+
This solves the problem.
|
7
|
+
|
8
|
+
Install
|
9
|
+
-------
|
10
|
+
Just install the gem and build the binary helper by running `rake`, it will
|
11
|
+
put it in `bin/hardstatus`, you can them move it in your PATH and call it as
|
12
|
+
backtick in the hardstatus.
|
13
|
+
|
14
|
+
Assuming you renamed the binary to `hs`.
|
15
|
+
|
16
|
+
```
|
17
|
+
backtick 1 1 1 hs right
|
18
|
+
```
|
19
|
+
|
20
|
+
This will define a right backtick, you have then to hadd the backtick to the
|
21
|
+
hardstatus, supposedly on the right.
|
22
|
+
|
23
|
+
You can have both left and right templates in the configuration.
|
24
|
+
|
25
|
+
Example
|
26
|
+
-------
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
right '#{irssi}#{email}#{hackers}#{processor}#{temperature}#{wireless}#{battery}'
|
30
|
+
|
31
|
+
def wrap (string)
|
32
|
+
"\005{= r}[\005{+b W}#{string}\005{= dr}] "
|
33
|
+
end
|
34
|
+
|
35
|
+
backtick :irssi, every: 1.second do
|
36
|
+
notifications = File.read(File.expand_path('~/.irssi/notifications')).gsub(':', '@').split(/, /)
|
37
|
+
|
38
|
+
unless notifications.empty?
|
39
|
+
wrap "IRC\005{-b r}|" + notifications.map {|n|
|
40
|
+
"\005{+b rW}#{n}\005{-b dd}"
|
41
|
+
}.join(' ')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'json'
|
46
|
+
require 'socket'
|
47
|
+
require 'timeout'
|
48
|
+
|
49
|
+
backtick :email, every: 3.second do
|
50
|
+
socket = TCPSocket.new('localhost', '9001')
|
51
|
+
socket.puts '* list unread'
|
52
|
+
|
53
|
+
notifications = JSON.parse(socket.gets)
|
54
|
+
|
55
|
+
unless notifications.empty?
|
56
|
+
wrap "Mail\005{-b r}|" + notifications.map {|name|
|
57
|
+
"\005{+b rW}#{name}\005{-b dd}"
|
58
|
+
}.join(' ')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
backtick :hackers, every: 5.seconds do
|
63
|
+
end
|
64
|
+
|
65
|
+
backtick :processor, every: 5.seconds do
|
66
|
+
wrap `(cpupower -c 0 frequency-info; cpupower -c 1 frequency-info) |
|
67
|
+
grep "current CPU" |
|
68
|
+
head -n 1 |
|
69
|
+
sed 's/^.*is //' |
|
70
|
+
sed 's/\.$//' |
|
71
|
+
tr -d '\n'`
|
72
|
+
end
|
73
|
+
|
74
|
+
backtick :temperature, every: 5.seconds do
|
75
|
+
`sensors`.match(/temp1:\s+([\d+\-.]+)/) { |m|
|
76
|
+
wrap(if m.to_i > 100
|
77
|
+
'STACCA STACCA STACC-'
|
78
|
+
else
|
79
|
+
"#{m} C"
|
80
|
+
end)
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
backtick :wireless, every: 5.seconds do
|
85
|
+
state = `iwconfig wlan0`
|
86
|
+
|
87
|
+
next if state =~ /No such device/
|
88
|
+
|
89
|
+
essid = state.match(/ESSID:"(.*?)"/)[1]
|
90
|
+
quality = state.match(/Quality=(.*?) /)[1]
|
91
|
+
|
92
|
+
if quality
|
93
|
+
wrap "#{essid}\005{-b r}|\005{+b W}#{quality}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
backtick :battery, every: 5.seconds do
|
98
|
+
state = `acpitool -B`
|
99
|
+
|
100
|
+
next if state =~ /100\.0%/
|
101
|
+
|
102
|
+
current = state.match(/([^\s]+%.*)$/)[1].sub(/, /, "\005{-b r}|\005{+b W}")
|
103
|
+
|
104
|
+
if state.match(/discharging/)
|
105
|
+
wrap "v|\005{+b W}#{current}"
|
106
|
+
else
|
107
|
+
wrap "^\005{-b r}|\005{+b W}#{current}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
Why in the world would you do that?
|
113
|
+
-----------------------------------
|
114
|
+
Because life is too easy, and tmux handling of windows isn't compatible with my
|
115
|
+
workflow, so I have to deal with the shittiness of GNU screen and this makes it
|
116
|
+
both usable and useful to my end.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require 'hardstatus'
|
3
|
+
|
4
|
+
fail 'no configuration file passed' if ARGV.empty?
|
5
|
+
|
6
|
+
EM.run {
|
7
|
+
hardstatus = Hardstatus.load(*ARGV)
|
8
|
+
hardstatus.start
|
9
|
+
|
10
|
+
%w[TERM INT HUP].each {|sig|
|
11
|
+
trap sig do
|
12
|
+
hardstatus.stop
|
13
|
+
|
14
|
+
EM.stop_event_loop
|
15
|
+
end
|
16
|
+
}
|
17
|
+
}
|
data/ext/hardstatus.c
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#include <sys/socket.h>
|
2
|
+
#include <sys/un.h>
|
3
|
+
#include <stdio.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <unistd.h>
|
6
|
+
#include <string.h>
|
7
|
+
#include <wordexp.h>
|
8
|
+
|
9
|
+
int
|
10
|
+
main (int argc, char* argv[])
|
11
|
+
{
|
12
|
+
struct sockaddr_un addr;
|
13
|
+
char buf[4096] = {0};
|
14
|
+
int fd;
|
15
|
+
char* path;
|
16
|
+
char* command;
|
17
|
+
|
18
|
+
if (argc == 2) {
|
19
|
+
wordexp_t p;
|
20
|
+
wordexp("$HOME/.hardstatus.ctl", &p, 0);
|
21
|
+
|
22
|
+
path = p.we_wordv[0];
|
23
|
+
command = argv[1];
|
24
|
+
}
|
25
|
+
else if (argc == 3) {
|
26
|
+
path = argv[1];
|
27
|
+
command = argv[2];
|
28
|
+
}
|
29
|
+
|
30
|
+
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
31
|
+
perror("socket error");
|
32
|
+
exit(-1);
|
33
|
+
}
|
34
|
+
|
35
|
+
memset(&addr, 0, sizeof(addr));
|
36
|
+
addr.sun_family = AF_UNIX;
|
37
|
+
strncpy(addr.sun_path, path, sizeof(addr.sun_path)-1);
|
38
|
+
|
39
|
+
if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
|
40
|
+
perror("connect error");
|
41
|
+
exit(-1);
|
42
|
+
}
|
43
|
+
|
44
|
+
send(fd, command, strlen(command), 0);
|
45
|
+
send(fd, "\r\n", 2, 0);
|
46
|
+
|
47
|
+
recv(fd, buf, 4096, 0);
|
48
|
+
printf("%s", buf);
|
49
|
+
|
50
|
+
return 0;
|
51
|
+
}
|
data/hardstatus.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Gem::Specification.new {|s|
|
2
|
+
s.name = 'hardstatus'
|
3
|
+
s.version = '0.0.1'
|
4
|
+
s.author = 'meh.'
|
5
|
+
s.email = 'meh@schizofreni.co'
|
6
|
+
s.homepage = 'http://github.com/meh/hardstatus'
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.summary = 'Hardstatus helpers for screen, because tmux just does not cut it for me.'
|
9
|
+
|
10
|
+
s.files = `git ls-files`.split("\n")
|
11
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
12
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
+
s.require_paths = ['lib']
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'eventmachine'
|
16
|
+
s.add_runtime_dependency 'thread'
|
17
|
+
}
|
data/lib/hardstatus.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
require 'thread/every'
|
12
|
+
require 'eventmachine'
|
13
|
+
|
14
|
+
require 'hardstatus/time'
|
15
|
+
require 'hardstatus/controller'
|
16
|
+
|
17
|
+
class Hardstatus
|
18
|
+
def self.load (path)
|
19
|
+
Hardstatus.new.load(path)
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :right, :left
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@backticks = {}
|
26
|
+
@controller = File.expand_path('~/.hardstatus.ctl')
|
27
|
+
end
|
28
|
+
|
29
|
+
def load (path = nil, &block)
|
30
|
+
if path
|
31
|
+
instance_eval File.read(File.expand_path(path)), path, 1
|
32
|
+
else
|
33
|
+
instance_exec(&block)
|
34
|
+
end
|
35
|
+
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def start
|
40
|
+
return if started?
|
41
|
+
|
42
|
+
@started = true
|
43
|
+
|
44
|
+
File.umask(0).tap {|old|
|
45
|
+
begin
|
46
|
+
@signature = EM.start_server(@controller, Controller, self)
|
47
|
+
ensure
|
48
|
+
File.umask(old)
|
49
|
+
end
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
def started?
|
54
|
+
@started
|
55
|
+
end
|
56
|
+
|
57
|
+
def stop
|
58
|
+
return unless started?
|
59
|
+
|
60
|
+
if @signature
|
61
|
+
EM.stop_server @signature
|
62
|
+
end
|
63
|
+
|
64
|
+
@started = false
|
65
|
+
end
|
66
|
+
|
67
|
+
def controller (path)
|
68
|
+
@controller = path
|
69
|
+
end
|
70
|
+
|
71
|
+
def right (template)
|
72
|
+
@right = template
|
73
|
+
end
|
74
|
+
|
75
|
+
def left (template)
|
76
|
+
@left = template
|
77
|
+
end
|
78
|
+
|
79
|
+
def backtick (name, options = {}, &block)
|
80
|
+
@backticks[name] = Thread.every(options[:every] || 1, &block)
|
81
|
+
end
|
82
|
+
|
83
|
+
def render (side)
|
84
|
+
template = case side
|
85
|
+
when :left then @left || ""
|
86
|
+
when :right then @right || ""
|
87
|
+
end
|
88
|
+
|
89
|
+
template.gsub(/\#{.*?}/) { |m|
|
90
|
+
@backticks[m.match(/\#{(.*?)}/)[1].to_sym].value!.to_s
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
class Hardstatus
|
12
|
+
|
13
|
+
class Controller < EventMachine::Protocols::LineAndTextProtocol
|
14
|
+
def initialize (hardstatus)
|
15
|
+
super
|
16
|
+
|
17
|
+
@hardstatus = hardstatus
|
18
|
+
end
|
19
|
+
|
20
|
+
def receive_line (line)
|
21
|
+
send_line @hardstatus.render(line.strip.to_sym)
|
22
|
+
|
23
|
+
close_connection_after_writing
|
24
|
+
end
|
25
|
+
|
26
|
+
def send_line (line)
|
27
|
+
raise ArgumentError, 'the line already has a newline character' if line.include? "\n"
|
28
|
+
|
29
|
+
send_data line.dup.force_encoding('BINARY') << "\r\n"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#--
|
2
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
3
|
+
# Version 2, December 2004
|
4
|
+
#
|
5
|
+
# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
6
|
+
# TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
7
|
+
#
|
8
|
+
# 0. You just DO WHAT THE FUCK YOU WANT TO.
|
9
|
+
#++
|
10
|
+
|
11
|
+
class Fixnum
|
12
|
+
def seconds
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
alias second seconds
|
17
|
+
alias s seconds
|
18
|
+
|
19
|
+
def milliseconds
|
20
|
+
self / 1000
|
21
|
+
end
|
22
|
+
|
23
|
+
alias millisecond milliseconds
|
24
|
+
alias ms milliseconds
|
25
|
+
|
26
|
+
def minutes
|
27
|
+
self * 60
|
28
|
+
end
|
29
|
+
|
30
|
+
alias minute minutes
|
31
|
+
|
32
|
+
def hours
|
33
|
+
self * 60 * 60
|
34
|
+
end
|
35
|
+
|
36
|
+
alias hour hours
|
37
|
+
|
38
|
+
def days
|
39
|
+
self * 60 * 60 * 24
|
40
|
+
end
|
41
|
+
|
42
|
+
alias day days
|
43
|
+
end
|
44
|
+
|
45
|
+
module Kernel
|
46
|
+
def second
|
47
|
+
1.second
|
48
|
+
end
|
49
|
+
|
50
|
+
def minute
|
51
|
+
1.minute
|
52
|
+
end
|
53
|
+
|
54
|
+
def hour
|
55
|
+
1.hour
|
56
|
+
end
|
57
|
+
|
58
|
+
def day
|
59
|
+
1.day
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hardstatus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- meh.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: eventmachine
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thread
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description:
|
42
|
+
email: meh@schizofreni.co
|
43
|
+
executables:
|
44
|
+
- hardstatus-daemon
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- README.md
|
49
|
+
- Rakefile
|
50
|
+
- bin/hardstatus-daemon
|
51
|
+
- ext/hardstatus.c
|
52
|
+
- hardstatus.gemspec
|
53
|
+
- lib/hardstatus.rb
|
54
|
+
- lib/hardstatus/controller.rb
|
55
|
+
- lib/hardstatus/time.rb
|
56
|
+
homepage: http://github.com/meh/hardstatus
|
57
|
+
licenses: []
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.0.0
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: Hardstatus helpers for screen, because tmux just does not cut it for me.
|
79
|
+
test_files: []
|