librr 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7c1431a1d77217312122796724510c4e77fb34d0
4
- data.tar.gz: 594faa85c5251131bc9f0679f1284daa321c7725
3
+ metadata.gz: 155602bd5086e0f8111e9a7e2d4d2cf9ab48c7b0
4
+ data.tar.gz: 70b707affb6b7c5871f9d02f0913eb35e9806838
5
5
  SHA512:
6
- metadata.gz: 0a300c702916d50729106e6f08c72fb9fd1984f182eabf22fa72c68a783c32814073209cbd6cdc5bcf150224c766ae37ec1708bad6c2b29764d57c7a757b3456
7
- data.tar.gz: a527e49131d00e7ab3a5542d55273db8fc0c9834eec178a6d6054052bec53060b772c76d70e1ed94132e688075c74bc15b4524c487be6f259bdb186703d61943
6
+ metadata.gz: 64bd8d2c2ad5fa9456b3f2f19887485f76baef67e12626df9bc037da5f2b2c0c8df19d2f6e51d78aa794192069a0f76084bfb337afa4ff4a1a67a50e42c325fa
7
+ data.tar.gz: b6fff23648956acbd98166c2377c8ad5f680d11dabd1c2dc223d69936becfcf9277b14a4b995ce8ee9a2306fc96fa6c5ccbc6129cd76d36fbd230a18f8648572
data/README.md CHANGED
@@ -26,13 +26,12 @@ gem install librr
26
26
  Start and stop background monitor process:
27
27
 
28
28
  ```sh
29
- librr start
30
- librr stop
29
+ librr daemon start
30
+ librr daemon stop
31
31
  ```
32
32
 
33
33
  It will start up automatically after first call to `librr search`,
34
34
  You don't need to start it manually.
35
- The background process name is: `librrd` and also start solr process.
36
35
 
37
36
 
38
37
  Config search directories:
@@ -50,10 +49,16 @@ Using search:
50
49
  librr search emacs
51
50
  ~/Dropbox/sync/docs/emacs.org:26: xxx emacs
52
51
  ~/Dropbox/sync/docs/gtd.org:230: bbb emacs
52
+
53
53
  # or using sortcut:
54
54
  librr s emacs
55
+
55
56
  # set return result rows(default 30):
56
57
  librr search emacs --rows 100
58
+
59
+ # under directory:
60
+ librr search emacs --location ./gtd
61
+ librr search emacs -l ./gtd
57
62
  ```
58
63
 
59
64
  Schecdule reindex:
@@ -61,3 +66,14 @@ Schecdule reindex:
61
66
  ```sh
62
67
  librr reindex [dir]
63
68
  ```
69
+
70
+ ## development
71
+
72
+ You can add `--debug` or `-d` argument to see what was happened under the hood: `librr add -d`.
73
+
74
+ And for debugging, you can run daemon sync with a terminal, and check the debug information on the stdout:
75
+
76
+ ```
77
+ librr daemon start --sync -d
78
+ ```
79
+
@@ -6,6 +6,7 @@ require 'librr/server_starter'
6
6
 
7
7
 
8
8
  class Librr::CmdClient
9
+ include Librr::Logger::ClassLogger
9
10
 
10
11
  def initialize host, port
11
12
  @host = host
@@ -29,7 +30,7 @@ class Librr::CmdClient
29
30
  rescue Errno::ECONNREFUSED => e
30
31
  end
31
32
 
32
- puts "server not start, starting.."
33
+ puts "daemon not start, starting.."
33
34
  ServerStarter.start_server(false)
34
35
  ServerStarter.wait_for_server_started do
35
36
  self.run_cmd cmd, **params
@@ -39,7 +40,7 @@ class Librr::CmdClient
39
40
  def run_cmd cmd, params={}
40
41
  params[:cmd] = cmd
41
42
  url = '/cmd'
42
- $logger.debug(:CmdClient){ "sending: #{params}" }
43
+ self.debug("sending: #{params}")
43
44
  result = Net::HTTP.post_form(URI.parse("http://#{@host}:#{@port}#{url}"), params)
44
45
  JSON.load(result.body)
45
46
  end
@@ -1,52 +1,76 @@
1
1
  require 'thor'
2
2
  require 'librr/cmd_client'
3
3
  require 'librr/settings'
4
+ require 'librr/my_thor'
4
5
 
5
6
 
6
- class Librr::CmdParser < Thor
7
+ class Librr::CmdParser < MyThor
7
8
 
8
- option :sync, type: :boolean
9
- desc 'start [--sync]', 'start background process'
10
- def start
11
- if @@client.check_start(options[:sync])
12
- puts 'server already started..'
13
- end
9
+ class << self
10
+ attr_accessor :client
14
11
  end
15
12
 
16
- desc 'stop', 'stop background process'
17
- def stop
18
- puts 'stopping..'
19
- @@client.cmd(:stop) rescue nil
13
+ class Daemon < MyThor
14
+ option :sync, type: :boolean, aliases: "-s"
15
+ desc 'start [--sync]', 'start background daemon process'
16
+ def start
17
+ if Librr::CmdParser.client.check_start(options[:sync])
18
+ puts 'daemon already started..'
19
+ end
20
+ end
21
+
22
+ desc 'stop', 'stop background daemon process'
23
+ def stop
24
+ puts 'stopping daemon..'
25
+ Librr::CmdParser.client.cmd(:stop) rescue nil
26
+ end
27
+
28
+ # desc 'restart', 'restart background daemon process'
29
+ # def restart
30
+ # puts 'daemon restarting..'
31
+ # Librr::CmdParser.client.cmd(:restart) rescue nil
32
+ # end
20
33
  end
21
34
 
35
+ desc "daemon SUBCOMMAND ...ARGS", "manage background daemon process"
36
+ subcommand "daemon", Daemon
37
+
38
+
22
39
  desc 'add DIR', 'add directory for indexing'
23
40
  def add(dir)
24
41
  puts "indexing: #{dir}"
25
- @@client.cmd(:add, dir: File.expand_path(dir))
42
+ self.class.client.cmd(:add, dir: File.expand_path(dir))
26
43
  end
27
44
 
28
45
  desc 'remove DIR', 'remove directory from indexing'
29
46
  def remove(dir)
30
47
  puts "removing: #{dir}"
31
- @@client.cmd(:remove, dir: File.expand_path(dir))
48
+ self.class.client.cmd(:remove, dir: File.expand_path(dir))
32
49
  end
33
50
 
34
51
  desc 'list', 'list all indexed directories'
35
52
  def list
36
- puts @@client.cmd(:list)
53
+ puts self.class.client.cmd(:list)
37
54
  end
38
55
 
39
56
  desc "reindex", "reindex files"
40
57
  def reindex
41
- @@client.cmd(:reindex)
58
+ self.class.client.cmd(:reindex)
42
59
  end
43
60
 
44
61
  option :rows, type: :numeric, default: 20
45
62
  option :all, type: :boolean
46
- desc 'search STRING', 'search string'
63
+ option :location, type: :string, aliases: "-l"
64
+ desc 'search STRING [--location DIR]', 'search string'
47
65
  def search(text)
66
+ location = (File.expand_path(options[:location]) if options[:location])
48
67
  puts "searching: #{text}"
49
- results = @@client.cmd(:search, text: text, all: options[:all], rows: options[:rows])
68
+ results = self.class.client.cmd(:search,
69
+ text: text,
70
+ all: options[:all],
71
+ rows: options[:rows],
72
+ location: location,
73
+ )
50
74
  if results.empty?
51
75
  puts "find no result"
52
76
  else
@@ -55,7 +79,7 @@ class Librr::CmdParser < Thor
55
79
  end
56
80
 
57
81
  def self.run!
58
- @@client = Librr::CmdClient.new('localhost', Settings.runner_port)
82
+ self.client = Librr::CmdClient.new('localhost', Settings.runner_port)
59
83
  self.start(ARGV)
60
84
  end
61
85
 
@@ -39,17 +39,24 @@ class Librr::CmdServer
39
39
  end
40
40
 
41
41
  def handle_cmd(params)
42
- self.info "on receive: #{params.to_s}"
42
+ self.debug "on receive: #{params.to_s}"
43
43
  case params['cmd']
44
44
  when 'ping'
45
45
  'pong'
46
46
 
47
47
  when 'stop'
48
- puts "server stopping.."
48
+ self.info "daemon stopping.."
49
49
  EM.next_tick{
50
50
  EM.stop
51
51
  }
52
52
 
53
+ when 'restart'
54
+ self.info "daemon restarting.."
55
+ EM.next_tick{
56
+ EM.stop
57
+ # todo
58
+ }
59
+
53
60
  when 'add'
54
61
  EM.next_tick{
55
62
  @@server.monitor.add_directory(params['dir'])
@@ -69,7 +76,12 @@ class Librr::CmdServer
69
76
  }
70
77
 
71
78
  when 'search'
72
- @@server.indexer.search(params['text'], rows: params['rows'], all: params['all'])
79
+ @@server.indexer.search(
80
+ params['text'],
81
+ rows: params['rows'],
82
+ all: params['all'],
83
+ location: params['location'],
84
+ )
73
85
 
74
86
  else
75
87
  raise Exception, "cmd unknown: #{params['cmd']}"
@@ -17,11 +17,11 @@ class Librr::DirMonitor
17
17
  @indexer = opts[:indexer]
18
18
 
19
19
  self.dirs = Configer.load_dir_config
20
- self.info "init dirs: #{self.dirs.to_a.to_s}"
20
+ self.debug "init dirs: #{self.dirs.to_a.to_s}"
21
21
  end
22
22
 
23
23
  def reindex
24
- self.info "reindex"
24
+ self.debug "reindex"
25
25
  @indexer.cleanup
26
26
  self.dirs.each do |dir|
27
27
  @indexer.index_directory(dir)
@@ -29,16 +29,16 @@ class Librr::DirMonitor
29
29
  end
30
30
 
31
31
  def add_directory(dir)
32
- self.info "add dir: #{dir}"
32
+ self.debug "add dir: #{dir}"
33
33
  @indexer.index_directory(dir)
34
34
  self.dirs.add(dir)
35
35
  Configer.save_dir_config(self.dirs)
36
- self.info "save dir: #{self.dirs.to_a.to_s}"
36
+ self.debug "save dir: #{self.dirs.to_a.to_s}"
37
37
  self.start
38
38
  end
39
39
 
40
40
  def remove_directory(dir)
41
- self.info "remove dir: #{dir}"
41
+ self.debug "remove dir: #{dir}"
42
42
  @indexer.remove_index_directory(dir)
43
43
  self.dirs.delete(dir)
44
44
  Configer.save_dir_config(self.dirs)
@@ -58,7 +58,7 @@ class Librr::DirMonitor
58
58
  @after_block = after_block
59
59
 
60
60
  if self.dirs.empty?
61
- self.info "DIR empty, not start process."
61
+ self.debug "DIR empty, not start process."
62
62
  self.post_init
63
63
  return
64
64
  end
@@ -79,7 +79,7 @@ class Librr::DirMonitor
79
79
  kill_process_by_file(self.class.pid_file)
80
80
 
81
81
  cmd = [FSEvent.watcher_path] + ["--file-events"] + self.dirs.to_a
82
- self.info "start process: #{cmd}"
82
+ self.debug "start process: #{cmd}"
83
83
  @pipe = EM.popen(cmd, DirWatcher, self)
84
84
  # TODO: write pid file
85
85
  end
@@ -97,7 +97,7 @@ class Librr::DirMonitor
97
97
  end
98
98
 
99
99
  def receive_data data
100
- self.info "on receive data: #{data}"
100
+ self.debug "on receive data: #{data}"
101
101
  changes = data.strip.split(':').map(&:strip).reject{|s| s == ''}
102
102
  changes.each do |file|
103
103
  @monitor.indexer.index_file(file)
@@ -105,7 +105,7 @@ class Librr::DirMonitor
105
105
  end
106
106
 
107
107
  def unbind
108
- self.info "dir monitor process stopped."
108
+ self.debug "dir monitor process stopped."
109
109
  @monitor.after_process_stop
110
110
  File.delete Librr::DirMonitor.pid_file rescue nil
111
111
  end
data/lib/librr/indexer.rb CHANGED
@@ -38,15 +38,15 @@ class Librr::Indexer
38
38
  include Librr::Logger::ClassLogger
39
39
 
40
40
  def post_init
41
- self.info "start solr"
41
+ self.debug "start solr"
42
42
  end
43
43
 
44
44
  def receive_data data
45
- self.info "receiving solr: #{data}"
45
+ self.debug "receiving solr: #{data}"
46
46
  end
47
47
 
48
48
  def unbind
49
- self.info "stop solr"
49
+ self.debug "stop solr"
50
50
  File.delete Librr::Indexer.pid_file rescue nil
51
51
  end
52
52
 
@@ -71,7 +71,7 @@ class Librr::Indexer
71
71
 
72
72
  def after_start
73
73
  @solr_started = true
74
- self.info 'after solr start'
74
+ self.debug 'after solr start'
75
75
 
76
76
  @solr = RSolr.connect(
77
77
  url: "http://localhost:#{Settings.solr_port}/solr",
@@ -90,7 +90,7 @@ class Librr::Indexer
90
90
  end
91
91
 
92
92
  def cleanup
93
- self.info 'cleanup'
93
+ self.debug 'cleanup'
94
94
  self.run_solr {
95
95
  @solr.delete_by_query '*:*'
96
96
  @solr.commit
@@ -98,7 +98,7 @@ class Librr::Indexer
98
98
  end
99
99
 
100
100
  def index_directory(dir)
101
- self.info "index dir: #{dir}"
101
+ self.debug "index dir: #{dir}"
102
102
  files = Dir.glob(File.join(dir, "**/*"))
103
103
  EM::Iterator.new(files)
104
104
  .each(
@@ -109,12 +109,12 @@ class Librr::Indexer
109
109
  iter.next
110
110
  end
111
111
  },
112
- proc { self.info "index dir finished: #{dir}" }
112
+ proc { self.debug "index dir finished: #{dir}" }
113
113
  )
114
114
  end
115
115
 
116
116
  def remove_index_directory(dir)
117
- self.info "remove dir: #{dir}"
117
+ self.debug "remove dir: #{dir}"
118
118
  self.run_solr {
119
119
  @solr.delete_by_query "filename:#{dir}*"
120
120
  @solr.commit
@@ -130,20 +130,19 @@ class Librr::Indexer
130
130
  }
131
131
 
132
132
  unless File.exists?(file)
133
- self.info "remove index file: #{file}"
133
+ self.debug "remove index file: #{file}"
134
134
  block.call if block
135
135
  return
136
136
  end
137
137
 
138
- self.info "index file: #{file}"
138
+ self.debug "index file: #{file}"
139
139
  f = File.open(file)
140
140
  enum = f.each.each_slice(SLICE_NUM).each_with_index
141
- self.info "file indexing...."
142
141
  DelayIterator.new(enum)
143
142
  .each(
144
143
  proc { |lines, i|
145
144
  data = lines.each_with_index.map do |line, j|
146
- num = SLICE_NUM * i + j
145
+ num = SLICE_NUM * i + j + 1
147
146
  line = fix_encoding(line).rstrip
148
147
  {id: SecureRandom.uuid, filename: file, linenum: num, line: line}
149
148
  end
@@ -153,7 +152,7 @@ class Librr::Indexer
153
152
  @solr.commit
154
153
  }
155
154
 
156
- self.info "working on lines: #{i*SLICE_NUM}"
155
+ self.debug "working on lines: #{i*SLICE_NUM}"
157
156
  },
158
157
  proc {
159
158
  f.close
@@ -163,13 +162,15 @@ class Librr::Indexer
163
162
  end
164
163
 
165
164
  def search(str, opts={})
166
- self.info "search: #{str}"
165
+ self.debug "search: #{str}"
167
166
 
168
167
  rows = opts[:rows] || 30
169
168
  rows = (2 ** 31 - 1) if opts[:all]
169
+ query = "line:#{str}"
170
+ query += " filename:#{opts[:location]}*" if opts[:location]
170
171
 
171
172
  result = self.run_solr {
172
- @solr.get 'select', params: {q: "line:#{str}", rows: rows}
173
+ @solr.get 'select', params: {q: query, rows: rows}
173
174
  }
174
175
 
175
176
  result['response']['docs'].map do |row|
data/lib/librr/lib.rb CHANGED
@@ -19,6 +19,16 @@ def redirect_std
19
19
  [wi, ro, re]
20
20
  end
21
21
 
22
+ def redirect_std_to_file(filename)
23
+ f = File.open(filename, 'a+')
24
+ f.sync = true
25
+
26
+ $stdout.reopen f
27
+ $stderr.reopen f
28
+
29
+ yield
30
+ end
31
+
22
32
 
23
33
  def fix_encoding text
24
34
  # solution copy from:
data/lib/librr/logger.rb CHANGED
@@ -1,21 +1,36 @@
1
1
  require 'logger'
2
+ require 'singleton'
3
+
2
4
 
3
5
  class Librr::Logger
6
+ include Singleton
4
7
 
5
8
  module ClassLogger
9
+ def logger
10
+ Librr::Logger.instance.logger
11
+ end
12
+
6
13
  def info(text)
7
- $logger.info(self.class.name){ text }
14
+ self.logger.info(self.class.name){ text }
15
+ end
16
+
17
+ def debug(text)
18
+ self.logger.debug(self.class.name){ text }
8
19
  end
9
20
  end
10
21
 
11
- def self.create_logger
22
+ def logger
23
+ @logger ||= self.create_logger
24
+ end
25
+
26
+ def logger=(logger)
27
+ @logger = logger
28
+ end
29
+
30
+ def create_logger
12
31
  logger = Logger.new(STDOUT)
13
- # logger.level = Logger::WARN
14
- logger.level = Logger::DEBUG
32
+ logger.level = Logger::WARN
15
33
  logger
16
34
  end
17
35
 
18
36
  end
19
-
20
- $logger ||= Librr::Logger.create_logger
21
-
@@ -0,0 +1,36 @@
1
+ require 'thor'
2
+
3
+ class MyThor < Thor
4
+ class_option :debug, type: :boolean, aliases: "-d"
5
+
6
+ class << self
7
+
8
+ protected
9
+
10
+ def method_added(meth)
11
+ meth = meth.to_s
12
+ @my_defined_methods ||= {}
13
+ return if @my_defined_methods[meth] or meth =~ /_old_/
14
+ @my_defined_methods[meth] = true
15
+ my_wrap_methods(meth)
16
+
17
+ super(meth)
18
+ end
19
+
20
+ def my_wrap_methods(meth)
21
+ old_meth = "_old_#{meth}"
22
+ alias_method old_meth, meth
23
+
24
+ define_method meth do |*args|
25
+ # set logger
26
+ if options[:debug]
27
+ Librr::Logger.instance.logger.level = Logger::DEBUG
28
+ end
29
+
30
+ self.send(old_meth, *args)
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ end
data/lib/librr/runner.rb CHANGED
@@ -10,6 +10,8 @@ EventMachine.kqueue = true if EventMachine.kqueue?
10
10
 
11
11
 
12
12
  class Librr::Runner
13
+ include Librr::Logger::ClassLogger
14
+
13
15
  def run!
14
16
  self.clear_pid
15
17
  @stoping = false
@@ -20,7 +22,7 @@ class Librr::Runner
20
22
  @stoping = true
21
23
 
22
24
  EM.stop
23
- puts "eventmachine graceful stops."
25
+ self.info "eventmachine stopping.."
24
26
  # todo commandline still show ^C?
25
27
  self.clear_pid
26
28
  end
@@ -35,13 +37,15 @@ class Librr::Runner
35
37
  indexer.start do
36
38
  monitor.start do
37
39
  server.start do
38
- puts "server started"
40
+ self.info "daemon started"
39
41
  self.write_pid
40
42
  end
41
43
  end
42
44
  end
43
45
 
44
46
  end
47
+
48
+ self.info "eventmachine stopped."
45
49
  end
46
50
 
47
51
  def write_pid
@@ -1,8 +1,12 @@
1
1
  # copy from gem daemons file: daemonize.rb
2
2
  # todo: may has secruity risk
3
3
  require 'librr/lib'
4
+ require 'librr/logger'
5
+ require 'librr/settings'
4
6
 
5
7
  module ServerStarter
8
+ include Librr::Logger::ClassLogger
9
+
6
10
  extend self
7
11
 
8
12
  def run
@@ -13,14 +17,21 @@ module ServerStarter
13
17
  end
14
18
 
15
19
  def start_server(sync)
16
- puts 'server starting..'
17
- return self.run if sync
20
+ puts 'daemon starting..'
21
+ if sync
22
+ Librr::Logger.instance.logger.level = Logger::DEBUG
23
+ return self.run
24
+ end
18
25
 
19
26
  Process.fork do
20
27
  sess_id = Process.setsid
21
28
  Process.fork do
22
29
  redirect_std do
23
- $logger.info "daemon started."
30
+ # for daemon, logger all information to log file
31
+ logger = Logger.new(Settings.in_dir('daemon.log'), 10, 1024000)
32
+ logger.level = Logger::DEBUG
33
+ Librr::Logger.instance.logger = logger
34
+ self.debug "daemon started."
24
35
  self.run
25
36
  end
26
37
  exit
@@ -32,13 +43,13 @@ module ServerStarter
32
43
  def wait_for_server_started &block
33
44
  5.times.each do
34
45
  sleep(2)
35
- puts 'waiting for server starting..'
46
+ puts 'waiting for daemon starting..'
36
47
 
37
48
  if File.exists?(Settings::PID_FILE)
38
49
  return block.call if block
39
50
  end
40
51
  end
41
- puts "server not starting, something is wrong."
52
+ puts "daemon not starting, something is wrong."
42
53
  exit
43
54
  end
44
55
  end
data/lib/librr/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Librr
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - linjunhalida
@@ -162,6 +162,7 @@ files:
162
162
  - lib/librr/indexer.rb
163
163
  - lib/librr/lib.rb
164
164
  - lib/librr/logger.rb
165
+ - lib/librr/my_thor.rb
165
166
  - lib/librr/runner.rb
166
167
  - lib/librr/server_starter.rb
167
168
  - lib/librr/settings.rb