codestock 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.document +5 -0
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +18 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +19 -0
  6. data/Rakefile +63 -0
  7. data/VERSION +1 -0
  8. data/bin/cdstk +12 -0
  9. data/bin/cdv +11 -0
  10. data/bin/cdview +11 -0
  11. data/bin/cdweb +11 -0
  12. data/codestock.gemspec +131 -0
  13. data/lib/codestock.rb +0 -0
  14. data/lib/common/dbdir.rb +37 -0
  15. data/lib/common/display_util.rb +62 -0
  16. data/lib/common/grenfiletest.rb +19 -0
  17. data/lib/common/grensnip.rb +37 -0
  18. data/lib/common/platform.rb +17 -0
  19. data/lib/common/string_snip.rb +61 -0
  20. data/lib/common/util.rb +98 -0
  21. data/lib/findgrep/findgrep.rb +408 -0
  22. data/lib/findgrep/result.rb +43 -0
  23. data/lib/gren/cli.rb +65 -0
  24. data/lib/gren.rb +6 -0
  25. data/lib/grendb/cli.rb +43 -0
  26. data/lib/grenweb/cli.rb +54 -0
  27. data/lib/grenweb/database.rb +182 -0
  28. data/lib/grenweb/grenweb.ru +35 -0
  29. data/lib/grenweb/grep.rb +52 -0
  30. data/lib/grenweb/help.rb +40 -0
  31. data/lib/grenweb/home.rb +40 -0
  32. data/lib/grenweb/html_renderer.rb +244 -0
  33. data/lib/grenweb/public/css/gren.css +63 -0
  34. data/lib/grenweb/public/images/gren-icon-mini.png +0 -0
  35. data/lib/grenweb/public/images/gren-icon.png +0 -0
  36. data/lib/grenweb/query.rb +82 -0
  37. data/lib/grenweb/searcher.rb +130 -0
  38. data/lib/grenweb/viewer.rb +52 -0
  39. data/lib/mkgrendb/cli.rb +89 -0
  40. data/lib/mkgrendb/cli_old.rb +49 -0
  41. data/lib/mkgrendb/grendbyaml.rb +76 -0
  42. data/lib/mkgrendb/mkgrendb.rb +296 -0
  43. data/test/file_test_utils.rb +59 -0
  44. data/test/runner.rb +11 -0
  45. data/test/test_dbdir.rb +59 -0
  46. data/test/test_gren.rb +10 -0
  47. data/test/test_gren_util.rb +34 -0
  48. data/test/test_grendbyaml.rb +109 -0
  49. data/test/test_grenweb_cli.rb +10 -0
  50. data/test/test_grenweb_database.rb +37 -0
  51. data/test/test_grenweb_html_renderer.rb +41 -0
  52. data/test/test_grenweb_query.rb +54 -0
  53. data/test/test_grenweb_searcher.rb +35 -0
  54. data/test/test_helper.rb +2 -0
  55. data/test/test_mkgrendb.rb +163 -0
  56. data/test/test_string_snip.rb +31 -0
  57. metadata +229 -0
@@ -0,0 +1,82 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief クエリーの解析
5
+ # @author ongaeshi
6
+ # @date 2010/10/21
7
+
8
+ require 'rubygems'
9
+ require 'rack'
10
+
11
+ module Grenweb
12
+ class Query
13
+ include Rack::Utils
14
+ attr_reader :query_string
15
+
16
+ OPTIONS = [
17
+ ['package', 'p'],
18
+ ['filepath', 'fpath', 'f'],
19
+ ['suffix', 's'],
20
+ ]
21
+
22
+ def initialize(request)
23
+ @query_string = unescape(request.path_info.gsub(/\A\/|\/\z/, ''))
24
+ init_hash
25
+ parse
26
+ end
27
+
28
+ def escape_html
29
+ Rack::Utils::escape_html(@query_string)
30
+ end
31
+
32
+ def empty?
33
+ keywords.size == 0 && packages.size == 0 && fpaths.size == 0 && suffixs.size == 0
34
+ end
35
+
36
+ def keywords
37
+ @hash['keywords']
38
+ end
39
+
40
+ def packages
41
+ calc_param(0)
42
+ end
43
+
44
+ def fpaths
45
+ calc_param(1)
46
+ end
47
+
48
+ def suffixs
49
+ calc_param(2)
50
+ end
51
+
52
+ private
53
+
54
+ def calc_param(index)
55
+ OPTIONS[index].inject([]){|result, item| result.concat @hash[item] }
56
+ end
57
+
58
+ def init_hash
59
+ @hash = {}
60
+ @hash['keywords'] = []
61
+
62
+ OPTIONS.flatten.each do |key|
63
+ @hash[key] = []
64
+ end
65
+ end
66
+
67
+ def parse
68
+ kp = OPTIONS.flatten.join('|')
69
+ parts = @query_string.scan(/(?:(#{kp}):)?(?:"(.+)"|(\S+))/)
70
+
71
+ parts.each do |key, quoted_value, value|
72
+ text = quoted_value || value
73
+ unless (key)
74
+ @hash['keywords'] << text
75
+ else
76
+ @hash[key] << text
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
@@ -0,0 +1,130 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief 検索処理本体
5
+ # @author ongaeshi
6
+ # @date 2010/10/13
7
+
8
+ require 'rubygems'
9
+ require 'rack'
10
+ require File.join(File.dirname(__FILE__), 'database')
11
+ require File.join(File.dirname(__FILE__), 'html_renderer')
12
+ require File.join(File.dirname(__FILE__), 'query')
13
+
14
+ module Grenweb
15
+ class Searcher
16
+ include Rack::Utils
17
+
18
+ def initialize
19
+ end
20
+
21
+ def call(env)
22
+ @request = Rack::Request.new(env)
23
+ @query = Query.new(@request)
24
+
25
+ @response = Rack::Response.new
26
+ @response["Content-Type"] = "text/html; charset=UTF-8"
27
+
28
+ @nth = 3 # マッチした行の前後何行を表示するか
29
+
30
+ @rendeler = HTMLRendeler.new(@request.script_name + '/..')
31
+
32
+ if @request.post? or @request['query']
33
+ post_request
34
+ else
35
+ search
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def post_request
42
+ query = @request['query'] || ''
43
+ if query.empty?
44
+ @request.path_info = "/"
45
+ else
46
+ @request.path_info = "/#{escape(query)}/"
47
+ end
48
+ @response.redirect(@request.url.split(/\?/, 2)[0])
49
+ @response.to_a
50
+ end
51
+
52
+ def search
53
+ render_header
54
+ render_search_box
55
+ render_search_result
56
+ render_footer
57
+ @response.to_a
58
+ end
59
+
60
+ def render_header
61
+ @response.write @rendeler.header("gren : #{@query.escape_html}", "gren")
62
+ end
63
+
64
+ def render_search_box
65
+ @response.write @rendeler.search_box(@query.escape_html)
66
+ end
67
+
68
+ def render_search_result
69
+ if @query.empty?
70
+ @response.write @rendeler.empty_summary
71
+ else
72
+ records, total_records, elapsed = Database.instance.search(@query.keywords, @query.packages, @query.fpaths, @query.suffixs, calcPage, calcLimit)
73
+ render_search_summary(records, total_records, elapsed)
74
+ records.each { |record| @response.write(@rendeler.result_record(record, @query.keywords, @nth)) }
75
+ render_pagination(calcPage, total_records)
76
+ end
77
+ end
78
+
79
+ def render_search_summary(records, total_records, elapsed)
80
+ pageStart = calcPage * calcLimit
81
+ @response.write @rendeler.search_summary(@query.query_string,
82
+ total_records,
83
+ (total_records.zero? ? 0 : pageStart + 1)..(pageStart + records.size),
84
+ elapsed)
85
+ end
86
+
87
+ def render_pagination(page, total_records)
88
+ return if @query.empty?
89
+ return if total_records < calcLimit
90
+
91
+ last_page = (total_records / calcLimit.to_f).ceil
92
+ @response.write("<div class='pagination'>\n")
93
+ if page > 0
94
+ @response.write(@rendeler.pagination_link(page - 1, "<<"))
95
+ end
96
+ last_page.times do |i|
97
+ if i == page
98
+ @response.write(@rendeler.pagination_span(i))
99
+ else
100
+ @response.write(@rendeler.pagination_link(i, i))
101
+ end
102
+ end
103
+ if page < (last_page - 1)
104
+ @response.write(@rendeler.pagination_link(page + 1, ">>"))
105
+ end
106
+ @response.write("</div>\n")
107
+ end
108
+
109
+ def render_footer
110
+ @response.write @rendeler.footer
111
+ end
112
+
113
+ private
114
+
115
+ # 1ページに表示する最大レコードを計算
116
+ def calcLimit
117
+ if @query.keywords.size == 0
118
+ 100
119
+ else
120
+ 20
121
+ end
122
+ end
123
+
124
+ # 現在ページを計算
125
+ def calcPage
126
+ (@request['page'] || 0).to_i
127
+ end
128
+ end
129
+ end
130
+
@@ -0,0 +1,52 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief ソースコードを表示する
5
+ # @author ongaeshi
6
+ # @date 2010/10/13
7
+
8
+ require 'rubygems'
9
+ require 'rack'
10
+ require File.join(File.dirname(__FILE__), 'database')
11
+ require File.join(File.dirname(__FILE__), 'html_renderer')
12
+
13
+ module Grenweb
14
+ class Viewer
15
+ include Rack::Utils
16
+
17
+ def initialize
18
+ end
19
+
20
+ def call(env)
21
+ @request = Rack::Request.new(env)
22
+ @response = Rack::Response.new
23
+ @response["Content-Type"] = "text/html; charset=UTF-8"
24
+
25
+ record, elapsed = Database.instance.record(req2query)
26
+
27
+ @rendeler = HTMLRendeler.new(@request.script_name + '/..')
28
+
29
+ if (record)
30
+ @response.write @rendeler.header("gren : #{record.shortpath}", "gren")
31
+ @response.write @rendeler.search_box("")
32
+ @response.write @rendeler.view_summary(record.shortpath, elapsed)
33
+ @response.write @rendeler.record_content(record)
34
+ else
35
+ @response.write @rendeler.header("gren : not found.", "gren")
36
+ @response.write @rendeler.search_box("")
37
+ @response.write @rendeler.empty_summary
38
+ end
39
+ @response.write @rendeler.footer
40
+
41
+ @response.to_a
42
+ end
43
+
44
+ private
45
+
46
+ def req2query
47
+ p @request.path_info
48
+ unescape(@request.path_info.gsub(/\A\/|\/z/, ''))
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,89 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'optparse'
3
+ require File.join(File.dirname(__FILE__), 'mkgrendb')
4
+ require File.join(File.dirname(__FILE__), '../common/dbdir.rb')
5
+ include CodeStock
6
+
7
+ module Mkgrendb
8
+ class CLI
9
+ def self.execute(stdout, arguments=[])
10
+ opt = OptionParser.new <<EOF
11
+ #{File.basename($0)} COMMAND [ARGS]
12
+
13
+ The most commonly used mkgrendb are:
14
+ init Init db.
15
+ update Update db.
16
+ add Add contents. (ex. ~/Documents/gren, git://github.com/ongaeshi/gren.git)
17
+ remove Remove contents.
18
+ list List all contents.
19
+ rebuild Rebuild db.
20
+ dump Dump database contents.
21
+ EOF
22
+
23
+ subopt = Hash.new
24
+
25
+ init_default = false
26
+ subopt['init'] = OptionParser.new("#{File.basename($0)} init")
27
+ subopt['init'].on('--default', 'Init db default path. (Maybe ~/.codestock)') { init_default = true }
28
+
29
+ subopt['update'] = OptionParser.new("#{File.basename($0)} update")
30
+ subopt['add'] = OptionParser.new("#{File.basename($0)} add content1 [content2 ...]")
31
+ subopt['remove'] = OptionParser.new("#{File.basename($0)} remove content1 [content2 ...]")
32
+ subopt['list'] = OptionParser.new("#{File.basename($0)} list")
33
+ subopt['rebuild'] = OptionParser.new("#{File.basename($0)} rebuild")
34
+ subopt['dump'] = OptionParser.new("#{File.basename($0)} dump")
35
+
36
+ opt.order!(arguments)
37
+ subcommand = arguments.shift
38
+
39
+ if (subopt[subcommand])
40
+ subopt[subcommand].parse!(arguments) unless arguments.empty?
41
+
42
+ db_dir = select_dbdir(subcommand, init_default)
43
+ obj = Mkgrendb.new(stdout, db_dir)
44
+
45
+ case subcommand
46
+ when 'init'
47
+ FileUtils.mkdir_p db_dir if (init_default)
48
+ obj.init
49
+ when 'update'
50
+ obj.update
51
+ when 'add'
52
+ obj.add *arguments
53
+ when 'remove'
54
+ obj.remove *arguments
55
+ when 'list'
56
+ obj.list
57
+ when 'rebuild'
58
+ obj.rebuild
59
+ when 'dump'
60
+ obj.dump
61
+ end
62
+ else
63
+ if subcommand
64
+ $stderr.puts "mkgrendb: '#{subcommand}' is not a mkgrendb command. See 'mkgrendb --help'"
65
+ else
66
+ stdout.puts opt.help
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def self.select_dbdir(subcommand, init_default)
74
+ if (subcommand == 'init')
75
+ if (init_default)
76
+ db_default_dir
77
+ else
78
+ '.'
79
+ end
80
+ else
81
+ if (dbdir?('.') || !dbdir?(db_default_dir))
82
+ '.'
83
+ else
84
+ db_default_dir
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'optparse'
3
+ require File.join(File.dirname(__FILE__), 'mkgrendb')
4
+
5
+ module Mkgrendb
6
+ class CLI
7
+ def self.execute(stdout, arguments=[])
8
+ input_yamls = []
9
+ isDump = false
10
+ isFull = false
11
+ isDelete = false
12
+ isReport = false
13
+
14
+ opt = OptionParser.new "#{File.basename($0)} INPUT_YAML1 [INPUT_YAML2 ...]"
15
+ opt.on('--ddb', "--default-db", "Create or Update default DB. (Plase set ENV['GRENDB_DEFAULT_DB'])") {|v| input_yamls << ENV['GRENDB_DEFAULT_DB']}
16
+ opt.on('--full', "Full update DB. (Delete and create)") {|v| isFull = true }
17
+ opt.on('--delete', "Delete DB. (Not delete yaml)") {|v| isDelete = true }
18
+ opt.on('--dump', "Dump DB.") {|v| isDump = true }
19
+ opt.on('--report', "Database Report.") {|v| isReport = true }
20
+ opt.parse!(arguments)
21
+
22
+ input_yamls.concat arguments
23
+
24
+ if (input_yamls.size >= 1)
25
+ input_yamls.each do |input_yaml|
26
+ obj = Mkgrendb.new(input_yaml)
27
+
28
+ if (isFull)
29
+ obj.full
30
+ stdout.puts
31
+ elsif (isDelete)
32
+ obj.delete
33
+ stdout.puts
34
+ elsif (isDump)
35
+ obj.dump
36
+ elsif (isReport)
37
+ obj.report
38
+ else
39
+ obj.update
40
+ stdout.puts
41
+ end
42
+
43
+ end
44
+ else
45
+ stdout.puts opt.help
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,76 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief
5
+ # @author ongaeshi
6
+ # @date 2011/02/20
7
+
8
+ require 'yaml'
9
+ require 'pathname'
10
+
11
+ module Mkgrendb
12
+ class GrendbYAML
13
+ class YAMLAlreadyExist < RuntimeError
14
+ end
15
+
16
+ class YAMLNotExist < RuntimeError
17
+ end
18
+
19
+ def self.create(path = ".")
20
+ yf = yaml_file(path)
21
+ raise YAMLAlreadyExist.new if FileTest.exist? yf
22
+ obj = GrendbYAML.new(yf, {'contents' => [], 'version' => 0.1})
23
+ obj.save
24
+ return obj
25
+ end
26
+
27
+ def self.load(path = ".")
28
+ yf = yaml_file(path)
29
+ raise YAMLNotExist.new unless FileTest.exist? yf
30
+ open(yf) do |f|
31
+ return GrendbYAML.new(yf, YAML.load(f.read()))
32
+ end
33
+ end
34
+
35
+ def add(*dirs)
36
+ contents.push(*dirs.map{|v|{"directory" => v}})
37
+ contents.uniq!
38
+ end
39
+
40
+ def remove(*dirs)
41
+ dirs.each {|f| contents.delete( {"directory" => f} ) }
42
+ end
43
+
44
+ def save
45
+ open(@yaml_file, "w") { |f| YAML.dump(@data, f) }
46
+ end
47
+
48
+ def contents
49
+ @data['contents']
50
+ end
51
+
52
+ def directorys
53
+ contents.map{|v|v["directory"]}
54
+ end
55
+
56
+ def version
57
+ @data['version']
58
+ end
59
+
60
+ def list
61
+ directorys
62
+ end
63
+
64
+ def self.yaml_file(path)
65
+ (Pathname.new(path) + 'grendb.yaml').to_s
66
+ end
67
+
68
+ private
69
+
70
+ def initialize(yaml_file, data)
71
+ @yaml_file = yaml_file
72
+ @data = data
73
+ end
74
+
75
+ end
76
+ end