cline 0.3.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,2 +1,2 @@
1
1
  rvm:
2
- - '1.9.3-p125'
2
+ - 1.9.3
data/README.md CHANGED
@@ -1,39 +1,78 @@
1
- # Cline - CLI Line Notifier [![Build Status](https://secure.travis-ci.org/hibariya/cline.png?branch=master)](http://travis-ci.org/hibariya/cline)
1
+ # Cline - Show recently news on the terminal[![Build Status](https://secure.travis-ci.org/hibariya/cline.png?branch=master)](http://travis-ci.org/hibariya/cline)
2
2
 
3
- Cline is a simple notification tool.
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
- In ~/.cline/config:
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.pool_size = 2000
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.out_stream = Cline::OutStreams::WithNotify.new($stdout)
26
- ## Or
27
- # config.out_stream = $stdout
64
+ config.collectors << Cline::Collectors::Feed
28
65
 
29
- config.append_collector Cline::Collectors::Feed
30
- ## Github:
31
- # config.append_collector Cline::Collectors::Github
32
- # Cline::Collectors::Github.login_name = 'hibariya'
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 OPML file:
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 0 5 # Or: cline tick --offset 0 --interval 5
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
- Open URL in the message:
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
- in ~/.screenrc
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
- `init` command initialize new sqlite3 database.
107
+ In ~/.screenrc:
75
108
 
76
109
  ```
77
- $ cline init
110
+ backtick 0 0 0 cline tick 5
78
111
  ```
79
112
 
80
- ## Collect
113
+ ## Cline daemon
81
114
 
82
- `collect` command collect new notifications from `Cline.collectors`.
115
+ When server is running then cline uses server process.
116
+ Using server is faster and less memory.
83
117
 
84
118
  ```
85
- $ cline collect
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
- ### Custom Collector
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
- ### Registration
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.append_collector MyCollector
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 STDOUT.
164
+ Default notifier is $stdout.
128
165
 
129
166
  ### Custom Notifyer
130
167
 
131
- Cline's notifier required `puts` instance method.
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
- ### Registration
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
- require_relative '../lib/cline'
4
+ trap :INT do
5
+ print "\r"
6
+ exit
7
+ end
5
8
 
6
- begin
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
- raise $!
18
- end
11
+ Cline.boot
12
+ Cline::Command.start
@@ -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{CLI Line Notifier}
12
- s.description = %q{Cline - CLI Line Notifier}
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
- #s.post_install_message = <<-EOM
15
- #EOM
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', ['>= 0.14.6']
23
- s.add_runtime_dependency 'activerecord', ['>= 3.1.1']
24
- s.add_runtime_dependency 'sqlite3', ['>= 1.3.4']
25
- s.add_runtime_dependency 'feedzirra', ['~> 0.0.31'] # FIXME builder dependency workaround...
26
- s.add_runtime_dependency 'notify', ['>= 0.3.0']
27
- s.add_runtime_dependency 'launchy', ['>= 2.1.0']
28
-
29
- s.add_development_dependency 'rake', ['>= 0.9.2']
30
- s.add_development_dependency 'ir_b', ['>= 1.4.0']
31
- s.add_development_dependency 'tapp', ['>= 1.1.0']
32
- s.add_development_dependency 'rspec', ['>= 2.6.0']
33
- s.add_development_dependency 'rr', ['>= 1.0.4']
34
- s.add_development_dependency 'fabrication', ['>= 1.2.0']
35
- s.add_development_dependency 'fuubar', ['>= 0.0.6']
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
@@ -1,70 +1,92 @@
1
1
  # coding: utf-8
2
2
 
3
- here = File.dirname(__FILE__)
4
- $LOAD_PATH.unshift here unless $LOAD_PATH.include?(here)
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 mkdir_if_needed
20
- path = Pathname.new(cline_dir)
21
- path.mkdir unless path.directory?
35
+ def collectors
36
+ @collectors ||= []
22
37
  end
23
38
 
24
- def setup_logger
25
- ActiveRecord::Base.logger = Logger.new(STDOUT)
26
- ActiveRecord::Base.logger.level = Logger::WARN
39
+ def jobs
40
+ @jobs ||= []
27
41
  end
28
42
 
29
- def establish_connection
30
- ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: "#{cline_dir}/cline.sqlite3", timeout: 10000
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 load_config_if_exists
34
- config = Pathname.new("#{cline_dir}/config")
35
- load config if config.exist?
50
+ def stdout
51
+ Thread.current[:stdout] || $stdout
36
52
  end
37
53
 
38
- def out_stream
39
- @out_stream || STDOUT
54
+ def stderr
55
+ Thread.current[:stderr] || $stderr
40
56
  end
41
57
 
42
- def out_stream=(stream)
43
- @out_stream = stream
58
+ def notify_io
59
+ @notify_io == $stdout ? stdout : @notify_io
44
60
  end
45
61
 
46
- def pool_size
47
- @pool_size
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 pool_size=(pool_size)
51
- @pool_size = pool_size
68
+ def load_default_config
69
+ @logger ||= default_logger
70
+ @notify_io ||= stdout
71
+ @notifications_limit ||= nil
52
72
  end
53
73
 
54
- collectors = []
55
- define_method(:collectors) { collectors }
56
- end
57
- end
74
+ private
58
75
 
59
- require 'logger'
60
- require 'pathname'
61
- require 'thor'
62
- require 'sqlite3'
63
- require 'active_record'
76
+ def mkdir_if_needed
77
+ FileUtils.mkdir_p cline_dir
78
+ end
64
79
 
65
- require 'cline/version'
66
- require 'cline/configure'
67
- require 'cline/notification'
68
- require 'cline/command'
69
- require 'cline/collectors'
70
- require 'cline/out_streams'
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
@@ -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