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.
@@ -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
@@ -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.
@@ -0,0 +1,5 @@
1
+ task :default => :build
2
+
3
+ task :build do
4
+ sh "#{ENV['CC'] || 'clang'} -O3 -o bin/hardstatus ext/hardstatus.c"
5
+ end
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }
@@ -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: []