cline 0.3.2 → 1.0.0
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.
- data/.travis.yml +1 -1
- data/README.md +77 -42
- data/bin/cline +7 -13
- data/cline.gemspec +32 -20
- data/lib/cline.rb +60 -38
- data/lib/cline/client.rb +28 -0
- data/lib/cline/collectors.rb +7 -3
- data/lib/cline/collectors/feed.rb +28 -22
- data/lib/cline/command.rb +93 -17
- data/lib/cline/configure.rb +4 -2
- data/lib/cline/monkey.rb +7 -0
- data/lib/cline/notification.rb +12 -12
- data/lib/cline/notify_io.rb +24 -0
- data/lib/cline/scheduled_job.rb +26 -0
- data/lib/cline/server.rb +102 -0
- data/lib/cline/version.rb +1 -1
- data/spec/lib/notification_spec.rb +7 -15
- data/spec/lib/server_spec.rb +22 -0
- data/spec/spec_helper.rb +3 -3
- data/spec/support/example_group_helper.rb +8 -0
- metadata +65 -93
- data/lib/cline/out_streams.rb +0 -34
data/.travis.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
rvm:
|
2
|
-
-
|
2
|
+
- 1.9.3
|
data/README.md
CHANGED
@@ -1,39 +1,78 @@
|
|
1
|
-
# Cline -
|
1
|
+
# Cline - Show recently news on the terminal[](http://travis-ci.org/hibariya/cline)
|
2
2
|
|
3
|
-
|
3
|
+
```
|
4
|
+
+-------------------------+ +-------+ +--------------------------------------+
|
5
|
+
| Notification Collectors | -> | Cline | -> | IO (STDOUT, File and Other notifier) |
|
6
|
+
+-------------------------+ +-------+ +--------------------------------------+
|
7
|
+
Collect any news Store notifications Put anywhere
|
8
|
+
```
|
9
|
+
|
10
|
+
Cline is a simple notification tool for CLI.
|
11
|
+
This tool collects automatically any Feeds and GitHub activities.
|
12
|
+
Those notifications shown on stdout or anywhere at good timing.
|
13
|
+
|
14
|
+
Like this:
|
15
|
+
|
16
|
+
```
|
17
|
+
$ cline show
|
18
|
+
[2012/11/27 01:18][5][184] TED: Ideas worth spreading http://icio.us/+a922037eaf9bb
|
19
|
+
```
|
20
|
+
|
21
|
+
A notification is structured by below contents:
|
22
|
+
|
23
|
+
* Published date of the entry and activity
|
24
|
+
* Displayed count
|
25
|
+
* Alias number for specify from CLI ([0-9a-z]+)
|
26
|
+
* Title or summary (includes source URL)
|
27
|
+
|
28
|
+
In most cases Cline used for backtick of screen. Like this:
|
29
|
+
|
30
|
+
```
|
31
|
+
[2012/12/01 23:12][9][1bt] Amazon Redshift http://aws.amazon.com/redshift/
|
32
|
+
[2012/12/01 23:12][9][1bu] My eBook build process and some PDF, EPUB and MOBI tips - Pat Shaughnessy http://patshaughnessy.net/2012/11/27/my-ebook-build-process-and-some-pdf-epub-and-mobi-tips
|
33
|
+
[2012/12/01 23:12][9][1bs] How to Clean Up Your Online Presence and Make a Great First Impression http://lifehacker.com/5963864/how-to-clean-up-your-online-presence-and-make-a-great-first-impression
|
34
|
+
```
|
35
|
+
|
36
|
+
You can open the URI of a notification. Like this:
|
4
37
|
|
5
38
|
```
|
6
|
-
|
7
|
-
| Collectors | ----------> | Cline | ----------> | OutStream |
|
8
|
-
+------------+ +-----------+ +-----------+
|
9
|
-
Collect any notifications Pool notifications Put anywhere
|
39
|
+
$ cline open 1bt
|
10
40
|
```
|
11
41
|
|
42
|
+
Cline decides priority of each notification automatically with 'displayed count' and 'published date'.
|
43
|
+
You can't control priority of Cline's output.
|
44
|
+
|
12
45
|
## Installation and Setting
|
13
46
|
|
14
47
|
```
|
15
48
|
$ gem install cline
|
16
|
-
$ cline init
|
49
|
+
$ cline init # database file will created under ~/.cline directory
|
17
50
|
```
|
18
51
|
|
19
|
-
|
52
|
+
An example of configuration file (~/.cline/config):
|
20
53
|
|
21
54
|
```ruby
|
55
|
+
ENV['NOTIFY'] = 'notify-send' # ensure notification behaviour if you use the notify gem
|
56
|
+
|
22
57
|
Cline.configure do |config|
|
23
|
-
config.
|
58
|
+
config.notifications_limit = 2000 # old notifications will be removed automatically
|
59
|
+
|
60
|
+
config.notify_io = Cline::NotifyIO::WithNotify.new
|
61
|
+
# Default is:
|
62
|
+
# config.notify_io = $stdout
|
24
63
|
|
25
|
-
config.
|
26
|
-
## Or
|
27
|
-
# config.out_stream = $stdout
|
64
|
+
config.collectors << Cline::Collectors::Feed
|
28
65
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
66
|
+
# Github:
|
67
|
+
config.collectors << Cline::Collectors::Github
|
68
|
+
Cline::Collectors::Github.login_name = 'hibariya'
|
69
|
+
|
70
|
+
# When server is running then collectors will run every hours.
|
71
|
+
config.jobs << Cline::ScheduledJob.new(-> { Time.now.min.zero? }, &:collect)
|
33
72
|
end
|
34
73
|
```
|
35
74
|
|
36
|
-
Write your RSS feeds
|
75
|
+
Write OPML file of your RSS feeds:
|
37
76
|
|
38
77
|
```
|
39
78
|
$ curl http://foo.examle.com/url/to/opml.xml > ~/.cline/feeds.xml
|
@@ -48,14 +87,14 @@ Collect notifications:
|
|
48
87
|
Show notifications:
|
49
88
|
|
50
89
|
```
|
51
|
-
$ cline tick
|
90
|
+
$ cline tick 5
|
52
91
|
[2012/05/02 02:34][9][w6] Introducing DuckDuckHack - Gabriel Weinberg's Blog http://www.gabrielweinberg.com/blog/2012/05/introducing-duckduckhack.html
|
53
92
|
| | |
|
54
93
|
`-- time | `-- alias
|
55
94
|
`----- display count
|
56
95
|
```
|
57
96
|
|
58
|
-
|
97
|
+
How to open a URL in the message: Use open command and specify notification alias.
|
59
98
|
|
60
99
|
```
|
61
100
|
$ cline open w6
|
@@ -63,29 +102,29 @@ Open URL in the message:
|
|
63
102
|
|
64
103
|
## Use case
|
65
104
|
|
66
|
-
|
67
|
-
|
68
|
-
```
|
69
|
-
backtick 0 0 0 cline tick 0 60
|
70
|
-
```
|
71
|
-
|
72
|
-
## initialize Database
|
105
|
+
In most cases Cline used for backtick of screen.
|
73
106
|
|
74
|
-
|
107
|
+
In ~/.screenrc:
|
75
108
|
|
76
109
|
```
|
77
|
-
|
110
|
+
backtick 0 0 0 cline tick 5
|
78
111
|
```
|
79
112
|
|
80
|
-
##
|
113
|
+
## Cline daemon
|
81
114
|
|
82
|
-
|
115
|
+
When server is running then cline uses server process.
|
116
|
+
Using server is faster and less memory.
|
83
117
|
|
84
118
|
```
|
85
|
-
$ cline
|
119
|
+
$ cline server start # start server
|
120
|
+
$ cline server reload # reload ~/.cline/config file
|
121
|
+
$ cline server stop # stop server
|
122
|
+
$ cline server status # show server status
|
86
123
|
```
|
87
124
|
|
88
|
-
|
125
|
+
## Customize
|
126
|
+
|
127
|
+
### Custom collector
|
89
128
|
|
90
129
|
*collector* required `collect` method.
|
91
130
|
|
@@ -106,29 +145,27 @@ example:
|
|
106
145
|
```
|
107
146
|
|
108
147
|
Cline::Collectors::Base class provides `create_or_pass` method.
|
109
|
-
It create a new unique notification.
|
148
|
+
It create a new (unique) notification.
|
110
149
|
|
111
|
-
|
112
|
-
|
113
|
-
in ~/.cline/config
|
150
|
+
In ~/.cline/config:
|
114
151
|
|
115
152
|
```ruby
|
116
153
|
require 'path/to/my_collector'
|
117
154
|
|
118
155
|
Cline.configure do |config|
|
119
156
|
# ...
|
120
|
-
config.
|
157
|
+
config.collectors << MyCollector
|
121
158
|
end
|
122
159
|
```
|
123
160
|
|
124
161
|
## Notifier
|
125
162
|
|
126
163
|
`show` and `tick` command uses Cline's notifier.
|
127
|
-
Default notifier is
|
164
|
+
Default notifier is $stdout.
|
128
165
|
|
129
166
|
### Custom Notifyer
|
130
167
|
|
131
|
-
Cline's notifier required `puts`
|
168
|
+
Cline's notifier required `puts` method.
|
132
169
|
|
133
170
|
example:
|
134
171
|
|
@@ -140,9 +177,7 @@ example:
|
|
140
177
|
end
|
141
178
|
```
|
142
179
|
|
143
|
-
|
144
|
-
|
145
|
-
in ~/.cline/config
|
180
|
+
In ~/.cline/config
|
146
181
|
|
147
182
|
```ruby
|
148
183
|
require 'path/to/my_notifier'
|
data/bin/cline
CHANGED
@@ -1,18 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
|
4
|
+
trap :INT do
|
5
|
+
print "\r"
|
6
|
+
exit
|
7
|
+
end
|
5
8
|
|
6
|
-
|
7
|
-
Cline::Command.start
|
8
|
-
rescue Exception
|
9
|
-
Pathname.new("#{Cline.cline_dir}/log").open('a') do |f|
|
10
|
-
f.puts '---'
|
11
|
-
f.puts Time.now
|
12
|
-
f.puts $!.class
|
13
|
-
f.puts $!.message
|
14
|
-
f.puts $!.backtrace.join("\n")
|
15
|
-
end
|
9
|
+
require 'cline'
|
16
10
|
|
17
|
-
|
18
|
-
|
11
|
+
Cline.boot
|
12
|
+
Cline::Command.start
|
data/cline.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
|
2
3
|
$:.push File.expand_path('../lib', __FILE__)
|
3
4
|
require 'cline/version'
|
4
5
|
|
@@ -8,31 +9,42 @@ Gem::Specification.new do |s|
|
|
8
9
|
s.authors = ['hibariya']
|
9
10
|
s.email = ['celluloid.key@gmail.com']
|
10
11
|
s.homepage = 'https://github.com/hibariya/cline'
|
11
|
-
s.summary = %q{
|
12
|
-
s.description = %q{
|
12
|
+
s.summary = %q{Show recently news on the terminal}
|
13
|
+
s.description = %q{Show recently news on the terminal.}
|
14
|
+
|
15
|
+
s.post_install_message = <<-EOM
|
16
|
+
**Important changes**
|
17
|
+
|
18
|
+
`tick` command usage has changed.
|
19
|
+
|
20
|
+
`cline tick OFFSET INTERVAL' -> `cline tick INTERVAL OFFSET'
|
13
21
|
|
14
|
-
|
15
|
-
|
22
|
+
**Cline server is available**
|
23
|
+
|
24
|
+
Cline uses daemon process if it's running.
|
25
|
+
|
26
|
+
$ cline server start # start server
|
27
|
+
$ cline server stop # stop server
|
28
|
+
$ cline server reload # reload config file
|
29
|
+
EOM
|
16
30
|
|
17
31
|
s.files = `git ls-files`.split("\n")
|
18
32
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
33
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
34
|
s.require_paths = ['lib']
|
21
35
|
|
22
|
-
s.add_runtime_dependency 'thor', ['
|
23
|
-
s.add_runtime_dependency 'activerecord', ['
|
24
|
-
s.add_runtime_dependency 'sqlite3', ['
|
25
|
-
s.add_runtime_dependency 'feedzirra', ['~> 0.
|
26
|
-
s.add_runtime_dependency 'notify', ['
|
27
|
-
s.add_runtime_dependency 'launchy', ['
|
28
|
-
|
29
|
-
s.add_development_dependency 'rake', ['
|
30
|
-
s.add_development_dependency '
|
31
|
-
s.add_development_dependency '
|
32
|
-
s.add_development_dependency '
|
33
|
-
s.add_development_dependency '
|
34
|
-
s.add_development_dependency '
|
35
|
-
s.add_development_dependency '
|
36
|
-
s.add_development_dependency 'simplecov', ['>= 0.5.3']
|
37
|
-
s.add_development_dependency 'activesupport', ['>= 3.1.1']
|
36
|
+
s.add_runtime_dependency 'thor', ['~> 0.16.0']
|
37
|
+
s.add_runtime_dependency 'activerecord', ['~> 3.1.8']
|
38
|
+
s.add_runtime_dependency 'sqlite3', ['~> 1.3.6']
|
39
|
+
s.add_runtime_dependency 'feedzirra', ['~> 0.1.3']
|
40
|
+
s.add_runtime_dependency 'notify', ['~> 0.4.0']
|
41
|
+
s.add_runtime_dependency 'launchy', ['~> 2.1.2']
|
42
|
+
|
43
|
+
s.add_development_dependency 'rake', ['~> 10.0.2']
|
44
|
+
s.add_development_dependency 'tapp', ['~> 1.4.0']
|
45
|
+
s.add_development_dependency 'rspec', ['~> 2.12.0']
|
46
|
+
s.add_development_dependency 'fabrication', ['~> 2.5.0']
|
47
|
+
s.add_development_dependency 'fuubar', ['~> 1.1.0']
|
48
|
+
s.add_development_dependency 'simplecov', ['~> 0.7.1']
|
49
|
+
s.add_development_dependency 'activesupport', ['~> 3.1.8']
|
38
50
|
end
|
data/lib/cline.rb
CHANGED
@@ -1,70 +1,92 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require 'fileutils'
|
4
|
+
require 'logger'
|
5
|
+
require 'cline/configure'
|
6
|
+
require 'cline/version'
|
5
7
|
|
6
8
|
module Cline
|
9
|
+
autoload :Collectors, 'cline/collectors'
|
10
|
+
autoload :Command, 'cline/command'
|
11
|
+
autoload :Notification, 'cline/notification'
|
12
|
+
autoload :Server, 'cline/server'
|
13
|
+
autoload :Client, 'cline/client'
|
14
|
+
autoload :NotifyIO, 'cline/notify_io'
|
15
|
+
autoload :ScheduledJob, 'cline/scheduled_job'
|
16
|
+
|
17
|
+
autoload :OutStreams, 'cline/notify_io' # obsolete
|
18
|
+
|
7
19
|
class << self
|
20
|
+
attr_accessor :logger, :notifications_limit
|
21
|
+
attr_writer :collectors, :notify_io, :jobs
|
22
|
+
|
8
23
|
def cline_dir
|
9
24
|
"#{ENV['HOME']}/.cline"
|
10
25
|
end
|
11
26
|
|
12
27
|
def boot
|
13
28
|
mkdir_if_needed
|
14
|
-
setup_logger
|
15
|
-
establish_connection
|
16
29
|
load_config_if_exists
|
30
|
+
load_default_config
|
31
|
+
|
32
|
+
self
|
17
33
|
end
|
18
34
|
|
19
|
-
def
|
20
|
-
|
21
|
-
path.mkdir unless path.directory?
|
35
|
+
def collectors
|
36
|
+
@collectors ||= []
|
22
37
|
end
|
23
38
|
|
24
|
-
def
|
25
|
-
|
26
|
-
ActiveRecord::Base.logger.level = Logger::WARN
|
39
|
+
def jobs
|
40
|
+
@jobs ||= []
|
27
41
|
end
|
28
42
|
|
29
|
-
def
|
30
|
-
|
43
|
+
def establish_database_connection
|
44
|
+
require 'active_record'
|
45
|
+
|
46
|
+
ActiveRecord::Base.logger = logger
|
47
|
+
ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: %(#{cline_dir}/cline.sqlite3), timeout: 10000, pool: 10
|
31
48
|
end
|
32
49
|
|
33
|
-
def
|
34
|
-
|
35
|
-
load config if config.exist?
|
50
|
+
def stdout
|
51
|
+
Thread.current[:stdout] || $stdout
|
36
52
|
end
|
37
53
|
|
38
|
-
def
|
39
|
-
|
54
|
+
def stderr
|
55
|
+
Thread.current[:stderr] || $stderr
|
40
56
|
end
|
41
57
|
|
42
|
-
def
|
43
|
-
@
|
58
|
+
def notify_io
|
59
|
+
@notify_io == $stdout ? stdout : @notify_io
|
44
60
|
end
|
45
61
|
|
46
|
-
def
|
47
|
-
|
62
|
+
def load_config_if_exists
|
63
|
+
config_file = "#{cline_dir}/config"
|
64
|
+
|
65
|
+
load config_file if File.exist?(config_file)
|
48
66
|
end
|
49
67
|
|
50
|
-
def
|
51
|
-
@
|
68
|
+
def load_default_config
|
69
|
+
@logger ||= default_logger
|
70
|
+
@notify_io ||= stdout
|
71
|
+
@notifications_limit ||= nil
|
52
72
|
end
|
53
73
|
|
54
|
-
|
55
|
-
define_method(:collectors) { collectors }
|
56
|
-
end
|
57
|
-
end
|
74
|
+
private
|
58
75
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
require 'sqlite3'
|
63
|
-
require 'active_record'
|
76
|
+
def mkdir_if_needed
|
77
|
+
FileUtils.mkdir_p cline_dir
|
78
|
+
end
|
64
79
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
80
|
+
def default_logger
|
81
|
+
Logger.new("#{cline_dir}/log").tap {|l| l.level = Logger::WARN }
|
82
|
+
end
|
83
|
+
|
84
|
+
public
|
85
|
+
|
86
|
+
# obsoletes
|
87
|
+
[%w(out_stream notify_io), %w(pool_size notifications_limit)].each do |obsolete, original|
|
88
|
+
alias_method obsolete, original
|
89
|
+
alias_method %(#{obsolete}=), %(#{original}=)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/lib/cline/client.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'socket'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Cline
|
7
|
+
class Client
|
8
|
+
def self.start(args)
|
9
|
+
new(args).invoke
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(args)
|
13
|
+
@args = args
|
14
|
+
end
|
15
|
+
|
16
|
+
def invoke
|
17
|
+
$stdout.sync = true
|
18
|
+
|
19
|
+
UNIXSocket.open Server.socket_file.to_path do |socket|
|
20
|
+
socket.puts @args.to_json
|
21
|
+
|
22
|
+
while line = socket.gets
|
23
|
+
puts line
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|