milkode 1.3.0 → 1.4.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/Gemfile CHANGED
@@ -15,6 +15,7 @@ gem 'archive-zip' , '>= 0.4.0'
15
15
  gem 'haml' , '>= 3.1.2'
16
16
  gem 'sass' , '>= 3.1.3'
17
17
  gem 'thor' , '>= 0.18.1'
18
+ gem 'i18n' , '~> 0.6.5'
18
19
 
19
20
  # Add dependencies to develop your gem here.
20
21
  # Include everything needed to run rake, tests, features, etc.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0
1
+ 1.4.0
data/bin/gmilk CHANGED
@@ -6,5 +6,5 @@
6
6
  require 'rubygems'
7
7
  require 'milkode/grep/cli_grep'
8
8
 
9
- Version = "1.3.0"
9
+ Version = "1.4.0"
10
10
  Milkode::CLI_Grep.execute(STDOUT, ARGV)
data/bin/milk CHANGED
@@ -6,5 +6,5 @@
6
6
  require 'rubygems'
7
7
  require 'milkode/cli'
8
8
 
9
- Version = "1.3.0"
9
+ Version = "1.4.0"
10
10
  Milkode::CLI.start(ARGV)
@@ -119,6 +119,10 @@ module Milkode
119
119
  def add(dirs, options)
120
120
  update_display_info(options)
121
121
 
122
+ if options[:from_file]
123
+ dirs = File.read(options[:from_file]).split("\n")
124
+ end
125
+
122
126
  print_result do
123
127
  # データベースを開く
124
128
  db_open
@@ -131,7 +135,8 @@ module Milkode
131
135
 
132
136
  # YAMLに追加
133
137
  package = Package.create(dir, options[:ignore])
134
- add_yaml(package)
138
+ skip_add = options[:from_file] && @yaml.find_name(package.name)
139
+ add_yaml(package) unless skip_add
135
140
 
136
141
  # オプション設定
137
142
  is_update_with_git_pull = git_protocol?(options, v)
@@ -139,7 +144,13 @@ module Milkode
139
144
  set_yaml_options(package, options, is_update_with_git_pull, is_update_with_svn_update)
140
145
 
141
146
  # アップデート
142
- update_dir_in(dir) unless options[:empty]
147
+ unless options[:empty]
148
+ if skip_add
149
+ update_package_in(package, options)
150
+ else
151
+ update_dir_in(dir)
152
+ end
153
+ end
143
154
  end
144
155
  rescue AddError => e
145
156
  error_alert(e.message)
@@ -281,17 +292,23 @@ module Milkode
281
292
  end
282
293
 
283
294
  def git_clone_in(url, options)
284
- alert("git", url)
285
-
286
295
  dst_dir = File.join(@db_dir, "packages/git")
287
296
  name = options[:name] || File.basename(url).sub(/\.git\Z/, "")
288
297
  filename = File.join(dst_dir, name)
289
298
 
290
- # git output progress to stderr.
291
- # `git clone #{url} #{filename} 2>&1`
299
+ unless File.exist?(filename)
300
+ # git output progress to stderr.
301
+ # `git clone #{url} #{filename} 2>&1`
292
302
 
293
- # with output
294
- system("git clone #{url} #{filename}")
303
+ # with output
304
+ if options[:branch_name]
305
+ alert("git", "#{url} (#{options[:branch_name]})")
306
+ system("git clone #{url} #{filename} -b #{options[:branch_name]}")
307
+ else
308
+ alert("git", url)
309
+ system("git clone #{url} #{filename}")
310
+ end
311
+ end
295
312
 
296
313
  filename
297
314
  end
@@ -1,18 +1,14 @@
1
1
  # -*- coding: utf-8 -*-
2
- #
3
- # @file
4
- # @brief
5
- # @author ongaeshi
6
- # @date 2011/06/25
7
-
8
2
  require 'rubygems'
9
3
  require 'sinatra'
4
+ require 'sass'
5
+ require 'haml'
6
+ require 'i18n'
7
+
10
8
  if ENV['MILKODE_SINATRA_RELOADER']
11
9
  require 'sinatra/reloader'
12
10
  also_reload '../../**/*.rb'
13
11
  end
14
- require 'sass'
15
- require 'haml'
16
12
 
17
13
  $LOAD_PATH.unshift '../..'
18
14
  require 'milkode/common/util'
@@ -25,7 +21,10 @@ require 'milkode/cdweb/lib/info_home'
25
21
  require 'milkode/cdweb/lib/info_package'
26
22
  require 'sinatra/url_for'
27
23
 
24
+ I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'locales', '*.yml').to_s]
25
+
28
26
  set :haml, :format => :html5
27
+ enable :sessions
29
28
 
30
29
  get '/js/:filename' do
31
30
  content_type :js
@@ -44,7 +43,7 @@ end
44
43
  get '/' do
45
44
  if Database.validate?
46
45
  @setting = WebSetting.new
47
- @version = "1.3.0"
46
+ @version = "1.4.0"
48
47
 
49
48
  @package_num = Database.instance.yaml_package_num
50
49
  @file_num = Database.instance.totalRecords
@@ -107,7 +106,7 @@ post '/command' do
107
106
  when 'favorite'
108
107
  Database.instance.set_fav(params[:name], params[:favorited] == 'true')
109
108
  @package_list = PackageList.new(Database.instance.grndb, url_for(''))
110
- "お気に入り: " + @package_list.favorite_list({})
109
+ t(:favorite) + ": " + @package_list.favorite_list({})
111
110
  end
112
111
  end
113
112
 
@@ -117,18 +116,19 @@ get '/home*' do |path|
117
116
  record = Database.instance.record(path)
118
117
  @package_list = PackageList.new(Database.instance.grndb, url_for(''))
119
118
  suburl = url_for('')
119
+ update_locale
120
120
 
121
121
  if path.empty?
122
122
  if (params[:query] and !params[:query].empty?)
123
- search(path, params, before, suburl)
123
+ search(path, params, before, suburl, @locale)
124
124
  else
125
- packages(params, before, suburl)
125
+ packages(params, before, suburl, @locale)
126
126
  end
127
127
  elsif (record)
128
128
  view(record, params, before)
129
129
  else
130
130
  if (params[:query] and !params[:query].empty?)
131
- search(path, params, before, suburl)
131
+ search(path, params, before, suburl, @locale)
132
132
  else
133
133
  filelist(path, params, before, suburl)
134
134
  end
@@ -192,9 +192,9 @@ helpers do
192
192
  value ||= "package"
193
193
 
194
194
  data = [
195
- ['all' , '全て' ],
196
- ['package' , 'パッケージ' ],
197
- ['directory', 'ディレクトリ'],
195
+ ['all' , t(:all) ],
196
+ ['package' , t(:package) ],
197
+ ['directory', t(:directory)],
198
198
  ]
199
199
 
200
200
  <<EOF
@@ -239,27 +239,28 @@ EOF
239
239
  flist = File.join("#{suburl}/home/#{path}", flistpath)
240
240
 
241
241
  package_name = ""
242
- modal_body = "全てのパッケージを更新しますか?"
242
+ modal_body = t(:update_all)
243
243
 
244
244
  if (path != "")
245
245
  package_name = path.split('/')[0]
246
- modal_body = "#{package_name} を更新しますか?"
246
+ update_locale
247
+ modal_body = I18n.t(:update_package, {package_name: package_name, locale: @locale})
247
248
  end
248
249
 
249
250
  info_path = "#{suburl}/info"
250
251
  info_path = File.join(info_path, package_name) if package_name != ""
251
252
 
252
253
  <<EOF
253
- #{headicon('go-home-5.png', suburl)}<a href="#{suburl}/home" class="headmenu">ホーム</a>&nbsp;
254
- #{headicon('directory.png', suburl)}<a href="#{flist}" class="headmenu">ディレクトリ</a>
255
- #{headicon('view-refresh-4.png', suburl)}<a href="#updateModal" class="headmenu" data-toggle="modal">パッケージを更新</a>&nbsp;
256
- #{headicon('info.png', suburl)}<a href="#{info_path}" class="headmenu">統計情報</a>&nbsp;
257
- #{headicon('help.png', suburl)}<a href="#{suburl}/help" class="headmenu">ヘルプ</a>
254
+ #{headicon('go-home-5.png', suburl)}<a href="#{suburl}/home" class="headmenu">#{t(:home)}</a>&nbsp;
255
+ #{headicon('directory.png', suburl)}<a href="#{flist}" class="headmenu">#{t(:directory)}</a>
256
+ #{headicon('view-refresh-4.png', suburl)}<a href="#updateModal" class="headmenu" data-toggle="modal">#{t(:update_packages)}</a>&nbsp;
257
+ #{headicon('info.png', suburl)}<a href="#{info_path}" class="headmenu">#{t(:stats)}</a>&nbsp;
258
+ #{headicon('help.png', suburl)}<a href="#{suburl}/help" class="headmenu">#{t(:help)}</a>
258
259
 
259
260
  <div id="updateModal" class="modal hide fade">
260
261
  <div class="modal-header">
261
262
  <a href="#" class="close" data-dismiss="modal">&times;</a>
262
- <h3>パッケージを更新</h3>
263
+ <h3>#{t(:update_packages)}</h3>
263
264
  </div>
264
265
  <div class="modal-body">
265
266
  <h4>#{modal_body}</h4>
@@ -292,7 +293,7 @@ EOF
292
293
  def create_favorite_list(package_list)
293
294
  <<EOF
294
295
  <div class="favorite_list">
295
- お気に入り:
296
+ #{t(:favorite)}:
296
297
  #{package_list.favorite_list(params)}
297
298
  </div>
298
299
  </div>
@@ -399,6 +400,32 @@ EOF
399
400
  def search_summary_hook(path)
400
401
  goto_github_project(path)
401
402
  end
403
+
404
+ ## for I18N
405
+ def ua_locale
406
+ # Pulls the browser's language
407
+ @env["HTTP_ACCEPT_LANGUAGE"][0,2]
408
+ end
409
+
410
+ def update_locale
411
+ unless @locale
412
+ begin
413
+ # Support session
414
+ @locale = params[:locale] || session[:locale] || ua_locale || 'en'
415
+ session[:locale] = @locale
416
+ rescue NameError # 'session' variable can't find during testing
417
+ @locale = 'en'
418
+ end
419
+
420
+ # Reload with sinatra-reloader
421
+ I18n.reload! if ENV['MILKODE_SINATRA_RELOADER']
422
+ end
423
+ end
424
+
425
+ def t(*args)
426
+ update_locale
427
+ I18n.t(*args, locale: @locale)
428
+ end
402
429
  end
403
430
 
404
431
  class Array
@@ -56,7 +56,7 @@ module Milkode
56
56
  haml :view
57
57
  end
58
58
 
59
- def search(path, params, before, suburl)
59
+ def search(path, params, before, suburl, locale)
60
60
  @setting = WebSetting.new
61
61
  @path = path
62
62
  query = Query.new(params[:query])
@@ -73,7 +73,7 @@ module Milkode
73
73
  if Util::gotoline_keyword?(query.keywords[0])
74
74
  searcher = SearchGotoLine.new(path, params, query, suburl)
75
75
  else
76
- searcher = SearchContents.new(path, params, query, suburl)
76
+ searcher = SearchContents.new(path, params, query, suburl, locale)
77
77
 
78
78
  if searcher.directjump?
79
79
  redirect searcher.directjump_url
@@ -105,24 +105,25 @@ module Milkode
105
105
  haml :filelist
106
106
  end
107
107
 
108
- def packages(params, before, suburl)
108
+ def packages(params, before, suburl, locale)
109
109
  @setting = WebSetting.new
110
110
  @title = "Package List"
111
111
  @path = ""
112
112
  packages = Database.instance.packages(params["sort"])
113
113
  @total_records = packages.size
114
+ @locale = locale
114
115
 
115
116
  @sort_change_content =
116
117
  [
117
- sort_change_content(params["sort"], '名前'),
118
+ sort_change_content(params["sort"], I18n.t(:name, locale: @locale)),
118
119
  '|',
119
- sort_change_content(params["sort"], '最近使った', 'viewtime'),
120
+ sort_change_content(params["sort"], I18n.t(:recently_viewed, locale: @locale), 'viewtime'),
120
121
  '|',
121
- sort_change_content(params["sort"], '追加順' , 'addtime'),
122
+ sort_change_content(params["sort"], I18n.t(:added, locale: @locale), 'addtime'),
122
123
  '|',
123
- sort_change_content(params["sort"], '更新順' , 'updatetime'),
124
+ sort_change_content(params["sort"], I18n.t(:updated, locale: @locale), 'updatetime'),
124
125
  '|',
125
- sort_change_content(params["sort"], 'お気に入り', 'favtime'),
126
+ sort_change_content(params["sort"], I18n.t(:favorite, locale: @locale), 'favtime'),
126
127
  ].join("\n")
127
128
 
128
129
  @record_content = packages.map do |v|
@@ -87,11 +87,11 @@ module Milkode
87
87
  end
88
88
 
89
89
  # 検索
90
- result, total_records = [], 0
90
+ records, total_records, result = [], 0, nil
91
91
 
92
92
  begin
93
93
  unless is_not_search
94
- result, total_records = @documents.search_with_match(
94
+ records, total_records, result = @documents.search_with_match(
95
95
  :patterns => patterns,
96
96
  :keywords => keywords,
97
97
  :paths => paths,
@@ -108,7 +108,7 @@ module Milkode
108
108
  end
109
109
 
110
110
  # 結果
111
- return result.map{|r| DocumentRecord.new(r)}, total_records
111
+ return records.map{|r| DocumentRecord.new(r)}, total_records, result
112
112
  end
113
113
 
114
114
  def selectAll(offset, limit)
@@ -26,7 +26,11 @@ module Milkode
26
26
 
27
27
  DEFAULT_WIDE_MATCH_RANGE = 7 # 未指定時のワイド検索範囲
28
28
 
29
- def initialize(path, params, query, suburl)
29
+ FILTER_BY_PACKAGE_NUM = 5
30
+ FILTER_BY_SUFFIX_NUM = 8
31
+ FILTER_BY_DIRECTORIES_FILES = 200
32
+
33
+ def initialize(path, params, query, suburl, locale)
30
34
  @path = path
31
35
  @params = params
32
36
  @q = query
@@ -37,11 +41,12 @@ module Milkode
37
41
  @is_sensitive = params[:sensitive] == 'on'
38
42
  @suburl = suburl
39
43
  @homeurl = @suburl + "/home/"
44
+ @locale = locale
40
45
 
41
46
  @searcher_fuzzy_gotoline = nil
42
47
 
43
48
  # 検索1 : クエリーそのまま
44
- @records, @total_records = Database.instance.search(@q.keywords, @q.multi_match_keywords, @q.packages, path, @q.fpaths, @q.suffixs, @q.fpath_or_packages, @offset, LIMIT_NUM)
49
+ @records, @total_records, result = Database.instance.search(@q.keywords, @q.multi_match_keywords, @q.packages, path, @q.fpaths, @q.suffixs, @q.fpath_or_packages, @offset, LIMIT_NUM)
45
50
  grep_contents(@q.keywords, @q.wide_match_range)
46
51
 
47
52
  # 検索2 : マッチしなかった時におすすめクエリーがある場合
@@ -92,6 +97,36 @@ module Milkode
92
97
  @match_files, t = Database.instance.search([], @q.multi_match_keywords, @q.packages, path, @q.fpaths, @q.suffixs, @q.fpath_or_packages + @q.keywords, @offset, MATH_FILE_LIMIT)
93
98
  end
94
99
  end
100
+
101
+ # Search4 : Drilldown
102
+ begin
103
+ @drilldown_packages = DocumentTable.drilldown(result, "package", FILTER_BY_PACKAGE_NUM)
104
+ @drilldown_directories = make_drilldown_directories(result)
105
+ @drilldown_suffixs = DocumentTable.drilldown(result, "suffix", FILTER_BY_SUFFIX_NUM)
106
+ rescue Groonga::InvalidArgument
107
+ @drilldown_packages = @drilldown_directories = @drilldown_suffixs = []
108
+ end
109
+ end
110
+
111
+ def make_drilldown_directories(result)
112
+ # Return empty if root path
113
+ return [] if @path == ""
114
+
115
+ # Drilldown
116
+ files = DocumentTable.drilldown(result, "restpath")
117
+ return [] if files.size > FILTER_BY_DIRECTORIES_FILES
118
+
119
+ files.map {|v|
120
+ Util::relative_path(v[1], @path.split("/")[1..-1].join("/")).to_s # 'path/to/file' -> 'to/file' (@path == 'path')
121
+ }.find_all {|v|
122
+ v.include?("/") # Extract directory
123
+ }.map {|v|
124
+ v.split("/")[0] # 'to/file' -> 'to'
125
+ }.inject(Hash.new(0)) {|hash, v|
126
+ hash[v] += 1; hash # Collect hash
127
+ }.map {|key, value|
128
+ [value, key] # To Array
129
+ }.to_a
95
130
  end
96
131
 
97
132
  def query
@@ -137,9 +172,12 @@ EOF
137
172
  def recommended_contents
138
173
  contents = []
139
174
 
140
- str = recommended_query_contents
175
+ str = drilldown_contents
141
176
  contents << str unless str.empty?
142
177
 
178
+ # str = recommended_query_contents
179
+ # contents << str unless str.empty?
180
+
143
181
  str = match_files_contents
144
182
  contents << str unless str.empty?
145
183
 
@@ -318,8 +356,11 @@ EOF
318
356
  path = Util::relative_path(record.shortpath, @path)
319
357
 
320
358
  if path != @prev
359
+ # dt = <<EOS
360
+ # <dt class='result-record'><a href='#{url + "#n#{coderay.highlight_lines[0]}"}'>#{path}</a>#{result_refinement(record)}</dt>
361
+ # EOS
321
362
  dt = <<EOS
322
- <dt class='result-record'><a href='#{url + "#n#{coderay.highlight_lines[0]}"}'>#{path}</a>#{result_refinement(record)}</dt>
363
+ <dt class='result-record'><a href='#{url + "#n#{coderay.highlight_lines[0]}"}'>#{path}</a></dt>
323
364
  EOS
324
365
  @prev = path
325
366
  else
@@ -373,24 +414,64 @@ EOS
373
414
  refinements = []
374
415
 
375
416
  # 拡張子で絞り込み
376
- refinements << "<a href='#{refinement_suffix(record.suffix)}'>.#{record.suffix}で絞り込み</a>" if record.suffix
417
+ refinements << "<a href='#{refinement_suffix(record.suffix)}'>.#{record.suffix}</a>" if record.suffix
377
418
 
378
419
  # ディレクトリで絞り込み
379
420
  path = Util::relative_path(record.shortpath, @path)
380
421
  dirname = path.to_s.split('/')[-2]
381
- refinements << "<a href='#{refinement_directory(record.shortpath + '/..')}'>#{dirname}/以下で再検索</a>" if dirname
422
+ refinements << "<a href='#{refinement_directory(record.shortpath + '/..')}'>#{dirname}/</a>" if dirname
382
423
 
383
424
  unless refinements.empty?
384
425
  space1 = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
385
426
  space2 = '&nbsp;&nbsp;,&nbsp;&nbsp;'
386
427
 
387
428
  <<EOF
388
- #{space1}<span id="result-refinement">[#{refinements.join(space2)}]</span>
429
+ # #{space1}<span id="result-refinement">#{I18n.t(:filter, {locale: @locale})} [#{refinements.join(space2)}]</span>
389
430
  EOF
390
431
  else
391
432
  ''
392
433
  end
434
+ end
435
+
436
+ def refinement_pathdir(dir)
437
+ refinement_directory(File.join(@path, dir))
438
+ end
439
+
440
+ def drilldown_contents
441
+ contents = []
442
+
443
+ result = drilldown_content(@drilldown_packages, I18n.t(:filter_by_package, {locale: @locale}), method(:refinement_directory))
444
+ contents << result unless result.empty?
445
+
446
+ result = drilldown_content(@drilldown_directories, I18n.t(:filter_by_directory, {locale: @locale}), method(:refinement_pathdir), '', '/', true)
447
+ contents << result unless result.empty?
448
+
449
+ result = drilldown_content(@drilldown_suffixs, I18n.t(:filter_by_suffix, {locale: @locale}), method(:refinement_suffix), '.')
450
+ contents << result unless result.empty?
451
+
452
+ unless contents.empty?
453
+ contents.join + "<hr>\n"
454
+ else
455
+ ""
456
+ end
457
+ end
458
+
459
+ def drilldown_content(array, title, to_url, prefix = "", suffix = "", disp_if_one = false)
460
+ unless array.empty? || (!disp_if_one && array.size == 1)
461
+ contents = []
393
462
 
463
+ array.each_with_index do |v, index|
464
+ if v[0] != 0
465
+ contents << "<strong><a href=\"#{to_url.call(v[1])}\" #{v[1]}(#{v[0]})>#{prefix + v[1] + suffix}</a></strong> (#{v[0]})"
466
+ else
467
+ contents << "..."
468
+ end
469
+ end
470
+
471
+ "<div class=\"filter_list\">#{title}: " + contents.join("&nbsp;&nbsp;&nbsp;") + "</div>"
472
+ else
473
+ ""
474
+ end
394
475
  end
395
476
 
396
477
  end
@@ -7,6 +7,7 @@
7
7
 
8
8
  require 'milkode/cdweb/lib/database'
9
9
  require 'yaml'
10
+ require 'i18n'
10
11
 
11
12
  module Milkode
12
13
  class WebSetting
@@ -51,9 +52,9 @@ module Milkode
51
52
 
52
53
  hash_method :favicon
53
54
 
54
- def about_milkode
55
+ def about_milkode(locale)
55
56
  if (@data[:display_about_milkode])
56
- ', <a href="http://milkode.ongaeshi.me">milkodeについて</a>'
57
+ ', <a href="http://milkode.ongaeshi.me">'+I18n.t(:about_milkode, locale: locale)+'</a>'
57
58
  else
58
59
  ''
59
60
  end
@@ -0,0 +1,35 @@
1
+ en:
2
+ search: Search
3
+ name: Name
4
+ recently_viewed: Viewed
5
+ added: New
6
+ updated: Updated
7
+ favorite: Favorites
8
+ packages: packages
9
+ files: files
10
+ help: Help
11
+ about_milkode: About Milkode
12
+ new_tab: New Tab
13
+ target: Target
14
+ package: Package
15
+ clear: Clear
16
+ onematch: one file one match
17
+ case_sensitive: case sensitive
18
+ total_files: files
19
+ searched: searched
20
+ matched_num: matched
21
+ sec: sec.
22
+ home: Home
23
+ directory: Directory
24
+ update_packages: Update Packages
25
+ stats: Stats
26
+ all: all
27
+ english: English
28
+ japanese: Japanese
29
+ update_all: Update all packages?
30
+ update_package: 'Update %{package_name}?'
31
+ filter: Filter
32
+ item: items
33
+ filter_by_package: Filter by Package
34
+ filter_by_suffix: Filter by Suffix
35
+ filter_by_directory: Filter by Directory
@@ -0,0 +1,35 @@
1
+ ja:
2
+ search: 検索
3
+ name: 名前
4
+ recently_viewed: 最近使った
5
+ added: 追加
6
+ updated: 更新
7
+ favorite: お気に入り
8
+ packages: のパッケージ
9
+ files: のファイル
10
+ help: ヘルプ
11
+ about_milkode: milkodeについて
12
+ new_tab: 新規タブ
13
+ target: 範囲
14
+ package: パッケージ
15
+ clear: クリア
16
+ onematch: 1ファイル1マッチ
17
+ case_sensitive: 大文字/小文字を区別
18
+ total_files: ファイル中
19
+ searched: ファイルを検索
20
+ matched_num: 件マッチ
21
+ sec: 秒
22
+ home: ホーム
23
+ directory: ディレクトリ
24
+ update_packages: パッケージを更新
25
+ stats: 統計情報
26
+ all: 全て
27
+ english: 英語
28
+ japanese: 日本語
29
+ update_all: 全てのパッケージを更新しますか?
30
+ update_package: '%{package_name} を更新しますか?'
31
+ filter: 絞り込み
32
+ item: 件
33
+ filter_by_package: パッケージで絞り込み
34
+ filter_by_suffix: 拡張子で絞り込み
35
+ filter_by_directory: ディレクトリで絞り込み
@@ -9,7 +9,7 @@
9
9
  .keyword.ss-box
10
10
  #{topic_path(@path, params)}
11
11
  .total-entries.ss-box
12
- #{@total_records}件(#{@elapsed}秒)
12
+ #{@total_records} #{t(:item)}(#{@elapsed}#{t(:sec)})
13
13
  .search-summary-hook.ss-box
14
14
  #{search_summary_hook(@path)}
15
15
  .ss-end
@@ -25,7 +25,7 @@
25
25
  .form
26
26
  %form(method="post" action="#{url_for '/search'}")
27
27
  %input(name="query" type="text" style="width: 419px;")
28
- %input(type="submit" value="検索")
28
+ %input(type="submit" value="#{t(:search)}")
29
29
  %input(name='pathname' type='hidden' value='#{url_for '/home'}')
30
30
 
31
31
  .row
@@ -35,16 +35,20 @@
35
35
 
36
36
  .row
37
37
  .span3
38
- %h2 最近使った
38
+ %h2
39
+ = t(:recently_viewed)
39
40
  = @package_list.top_view
40
41
  .span3
41
- %h2 追加
42
+ %h2
43
+ = t(:added)
42
44
  = @package_list.top_add
43
45
  .span3
44
- %h2 更新
46
+ %h2
47
+ = t(:updated)
45
48
  = @package_list.top_update
46
49
  .span3
47
- %h2 お気に入り
50
+ %h2
51
+ = t(:favorite)
48
52
  = @package_list.top_fav
49
53
 
50
54
  %hr
@@ -52,17 +56,18 @@
52
56
  .row
53
57
  .span4.offset4
54
58
  .footer
55
- <a href="#{url_for '/home'}">#{@package_num}</a>のパッケージ<br>
56
- <a href="#{url_for '/home?query=f:*'}">#{@file_num}</a>のファイル<br>
57
- <a href="#{url_for '/help'}">ヘルプ</a>
58
- = @setting.about_milkode
59
+ <a href="#{url_for '/home'}">#{@package_num}</a> #{t(:packages)}<br>
60
+ <a href="#{url_for '/home?query=f:*'}">#{@file_num}</a> #{t(:files)}<br>
61
+ [<a href="#{url_for '/?locale=en'}">#{t(:english)}</a> | <a href="#{url_for '/?locale=ja'}">#{t(:japanese)}</a>]<br>
62
+ <a href="#{url_for '/help'}">#{t(:help)}</a>
63
+ = @setting.about_milkode(@locale)
59
64
 
60
65
  %script(type='text/javascript' src='#{url_for '/js/jquery-1.7.2.min.js'}')
61
66
  %script(type='text/javascript' src='#{url_for '/js/jquery-ui-1.8.22.custom.min.js'}')
62
67
  %script(type='text/javascript' src='#{url_for '/js/jquery.multiselect.min.js'}')
63
68
  %script(type='text/javascript' src='#{url_for '/js/jquery.multiselect.filter.min.js'}')
64
69
  %script(type='text/javascript' src='#{url_for '/js/milkode.js'}')
65
-
70
+
66
71
 
67
72
 
68
73
 
@@ -274,3 +274,6 @@ label.ui-corner-all {
274
274
  background-color: #FFEE55;
275
275
  }
276
276
 
277
+ .filter_list {
278
+ margin-top: 3px;
279
+ }
@@ -7,7 +7,7 @@
7
7
  .sort-change.ss-box
8
8
  #{@sort_change_content}
9
9
  .total-entries.ss-box
10
- #{@total_records}</span>件(#{@elapsed}秒)
10
+ #{@total_records} #{t(:item)}(#{@elapsed}#{t(:sec)})
11
11
  .ss-end
12
12
 
13
13
  ~ @record_content
@@ -9,11 +9,12 @@
9
9
  .keyword.ss-box
10
10
  #{topic_path(@path, params)}
11
11
  .hit-num.ss-box
12
- #{@total_records}</span>ファイル中
12
+ #{@total_records}</span>
13
+ = t(:total_files)
13
14
  .search-range.ss-box
14
- #{@range.first} - #{@range.last}ファイルを検索
15
+ #{@range.first} - #{@range.last} #{t(:searched)}
15
16
  .match-num.ss-box
16
- #{@match_num}</span>件マッチ(#{@elapsed}秒)
17
+ #{@match_num}</span> #{t(:matched_num)}(#{@elapsed}#{t(:sec)})
17
18
  .search-summary-hook.ss-box
18
19
  #{search_summary_hook(@path)}
19
20
  .ss-end
@@ -6,16 +6,16 @@
6
6
  %form(name="searchform" action="#{url_for '/search'}" method="post")
7
7
  %p
8
8
  %input#query(name="query" size="70" type="text" style="width: 419px;"){:value => params[:query]}
9
- %input#search(type="submit" name="search" value="検索" onclick="set_pathname()")
10
- %input#newtab(type="submit" name="newtab" value="新規タブ" onclick="open_newtab(); return false;")
11
- %input#clear(type="submit" name="clear" value="クリア" onclick="set_pathname()")
9
+ %input#search(type="submit" name="search" value="#{t(:search)}" onclick="set_pathname()")
10
+ %input#newtab(type="submit" name="newtab" value="#{t(:new_tab)}" onclick="open_newtab(); return false;")
11
+ %input#clear(type="submit" name="clear" value="#{t(:clear)}" onclick="set_pathname()")
12
12
  %br
13
- 範囲:
13
+ = t(:target) + ":"
14
14
  = create_select_shead(params[:shead])
15
- パッケージ:
15
+ = t(:package) + ":"
16
16
  = create_select_package(@path)
17
- = create_checkbox('onematch', params[:onematch], '1ファイル1マッチ')
18
- = create_checkbox('sensitive', params[:sensitive], '大文字/小文字を区別')
17
+ = create_checkbox('onematch', params[:onematch], t(:onematch))
18
+ = create_checkbox('sensitive', params[:sensitive], t(:case_sensitive))
19
19
  = create_favorite_list(@package_list)
20
20
 
21
21
  %input(name="pathname" type="hidden" value="")
data/lib/milkode/cli.rb CHANGED
@@ -32,17 +32,20 @@ Samples:
32
32
  milk add /path/to/addon.xpi
33
33
  milk add http://example.com/urlfile.zip
34
34
  milk add git://github.com/ongaeshi/milkode.git
35
+ milk add git://github.com/ongaeshi/milkode.git -b develop -n milkode_develop
35
36
  EOF
37
+ option :branch_name, :type => :string, :aliases => '-b', :desc => 'Branch name.'
36
38
  option :empty, :type => :boolean, :desc => 'Add empty package.'
37
39
  option :ignore, :type => :array, :aliases => '-i', :desc => 'Ignore path.'
38
40
  option :name, :type => :string, :aliases => '-n', :desc => 'Rename package.'
39
41
  option :no_auto_ignore, :type => :boolean, :aliases => '--ni', :desc => 'Disable auto ignore.'
40
42
  option :protocol, :type => :string, :aliases => '-p', :desc => 'Specify protocol. (git, svn)'
43
+ option :from_file, :type => :string, :desc => 'Import from file'
41
44
 
42
45
  option :verbose, :type => :boolean, :aliases => '-v', :desc => 'Be verbose.'
43
46
 
44
47
  def add(*args)
45
- if args.empty?
48
+ if args.empty? && !options[:from_file]
46
49
  CLI.task_help(shell, "add")
47
50
  else
48
51
  cdstk.add(args, options)
@@ -187,11 +187,11 @@ module Milkode
187
187
  end
188
188
 
189
189
  def git_url?(src)
190
- (src =~ /^(:?git[:@])|(:?ssh:)/) != nil
190
+ (src =~ /^(?:git[:@])|(?:ssh:)|(?:\.git\Z)/) != nil
191
191
  end
192
192
 
193
193
  def svn_url?(src)
194
- (src =~ /^(:?svn|svn\+ssh):\/\//) != nil
194
+ (src =~ /^(?:svn|svn\+ssh):\/\//) != nil
195
195
  end
196
196
 
197
197
  # StringIO patch
@@ -250,7 +250,7 @@ module Milkode
250
250
  pos = 0
251
251
 
252
252
  loop do
253
- r = src.match(/#{keyword}/i, pos) do |m|
253
+ r = src.match(/#{Regexp.escape(keyword)}/i, pos) do |m|
254
254
  s = m.begin(0)
255
255
  l = keyword.length
256
256
  e = s+l
@@ -305,6 +305,27 @@ module Milkode
305
305
  nil
306
306
  end
307
307
  end
308
+
309
+ def str2kcode(str)
310
+ case str.downcase
311
+ when 'none'
312
+ Kconv::NOCONV
313
+ when 'jis'
314
+ Kconv::JIS
315
+ when 'sjis'
316
+ Kconv::SJIS
317
+ when 'euc'
318
+ Kconv::EUC
319
+ when 'ascii'
320
+ Kconv::ASCII
321
+ when 'utf8'
322
+ Kconv::UTF8
323
+ when 'utf16'
324
+ Kconv::UTF16
325
+ else
326
+ nil
327
+ end
328
+ end
308
329
 
309
330
  end
310
331
  end
@@ -11,25 +11,57 @@ require 'milkode/common/util'
11
11
  module Milkode
12
12
  class DocumentTable
13
13
  def self.define_schema
14
- Groonga::Schema.define do |schema|
15
- schema.create_table("documents", :type => :hash) do |table|
16
- table.string("path")
17
- table.string("package")
18
- table.string("restpath")
19
- table.text("content")
20
- table.time("timestamp")
21
- table.text("suffix")
14
+ begin
15
+ Groonga::Schema.define do |schema|
16
+ schema.create_table("documents", :type => :hash) do |table|
17
+ table.string("path")
18
+ table.string("package")
19
+ table.string("restpath")
20
+ table.text("content")
21
+ table.time("timestamp")
22
+ table.string("suffix")
23
+ end
24
+
25
+ schema.create_table("terms",
26
+ :type => :patricia_trie,
27
+ :key_normalize => true,
28
+ :default_tokenizer => "TokenBigramSplitSymbolAlphaDigit") do |table|
29
+ table.index("documents.path", :with_position => true)
30
+ table.index("documents.package", :with_position => true)
31
+ table.index("documents.restpath", :with_position => true)
32
+ table.index("documents.content", :with_position => true)
33
+ table.index("documents.suffix", :with_position => true)
34
+ end
22
35
  end
36
+ rescue Groonga::Schema::ColumnCreationWithDifferentOptions
37
+ puts <<EOF
38
+ WARNING: Milkode database is old. (Renewal at 1.4.0)
39
+ Can't get the new features. Please execute rebuild command.
40
+
41
+ $ milk rebuild --all
42
+
43
+ EOF
44
+
45
+ Groonga::Schema.define do |schema|
46
+ schema.create_table("documents", :type => :hash) do |table|
47
+ table.string("path")
48
+ table.string("package")
49
+ table.string("restpath")
50
+ table.text("content")
51
+ table.time("timestamp")
52
+ table.text("suffix")
53
+ end
23
54
 
24
- schema.create_table("terms",
25
- :type => :patricia_trie,
26
- :key_normalize => true,
27
- :default_tokenizer => "TokenBigramSplitSymbolAlphaDigit") do |table|
28
- table.index("documents.path", :with_position => true)
29
- table.index("documents.package", :with_position => true)
30
- table.index("documents.restpath", :with_position => true)
31
- table.index("documents.content", :with_position => true)
32
- table.index("documents.suffix", :with_position => true)
55
+ schema.create_table("terms",
56
+ :type => :patricia_trie,
57
+ :key_normalize => true,
58
+ :default_tokenizer => "TokenBigramSplitSymbolAlphaDigit") do |table|
59
+ table.index("documents.path", :with_position => true)
60
+ table.index("documents.package", :with_position => true)
61
+ table.index("documents.restpath", :with_position => true)
62
+ table.index("documents.content", :with_position => true)
63
+ table.index("documents.suffix", :with_position => true)
64
+ end
33
65
  end
34
66
  end
35
67
  end
@@ -299,8 +331,8 @@ module Milkode
299
331
  :offset => offset,
300
332
  :limit => limit)
301
333
 
302
- # 検索結果のレコード(limitの影響を受ける), 総マッチ数(limitの影響を受けない)
303
- return records, result.size
334
+ # 検索結果のレコード(limitの影響を受ける), 総マッチ数(limitの影響を受けない), result(Groonga::Hash)
335
+ return records, result.size, result
304
336
  end
305
337
 
306
338
  # マッチしたレコードのみを返す
@@ -308,6 +340,11 @@ module Milkode
308
340
  records, match_total = search_with_match(options)
309
341
  records
310
342
  end
343
+
344
+ def self.drilldown(result, column, num = nil)
345
+ drilled = result.group(column).map {|record| [record.n_sub_records, record.key]}.sort_by {|a| a[0]}.reverse
346
+ num ? drilled[0, num] : drilled
347
+ end
311
348
 
312
349
  def select_all_sort_by_shortpath(offset = 0, limit = -1)
313
350
  result = @table.select
@@ -79,6 +79,7 @@ EOF
79
79
  opt.on('-n NUM', 'Limits the number of match to show.') {|v| option.matchCountLimit = v.to_i }
80
80
  opt.on('--no-external', 'Disable auto external.') {|v| my_option[:no_external] = true }
81
81
  opt.on('--no-snip', 'There being a long line, it does not snip.') {|v| option.noSnip = true }
82
+ opt.on('-o ENCODE', '--output-encode ENCODE', 'Specify output encode(none, jis, sjis, euc, ascii, utf8, utf16). Default is "utf8"') {|v| option.output_kcode = Util::str2kcode(v) }
82
83
  opt.on('-p PACKAGE', '--package PACKAGE', 'Specify search package.') {|v| setup_package(option, my_option, v) }
83
84
  opt.on('-r', '--root', 'Search from package root.') {|v| current_dir = package_root_dir(File.expand_path(".")); my_option[:find_mode] = true }
84
85
  opt.on('-s SUFFIX', '--suffix SUFFIX', 'Suffix.') {|v| option.suffixs << v; my_option[:find_mode] = true }
@@ -345,6 +345,11 @@ module Milkode
345
345
 
346
346
  line = GrenSnip::snip(line, match_datas) unless (@option.noSnip)
347
347
 
348
+ if @option.output_kcode != Kconv::UTF8
349
+ header = Kconv.kconv(header, @option.output_kcode)
350
+ line = Kconv.kconv(line, @option.output_kcode)
351
+ end
352
+
348
353
  unless (@option.colorHighlight)
349
354
  stdout.puts header + line
350
355
  else
@@ -23,6 +23,7 @@ module Milkode
23
23
  :ignoreFiles,
24
24
  :ignoreDirs,
25
25
  :kcode,
26
+ :output_kcode,
26
27
  :noSnip,
27
28
  :dbFile,
28
29
  :groongaOnly,
@@ -49,6 +50,7 @@ module Milkode
49
50
  [],
50
51
  [],
51
52
  Kconv::UTF8, # Platform.get_shell_kcode,
53
+ Kconv::UTF8,
52
54
  false,
53
55
  nil,
54
56
  false,
data/milkode.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "milkode"
8
- s.version = "1.3.0"
8
+ s.version = "1.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["ongaeshi"]
12
- s.date = "2013-10-28"
12
+ s.date = "2013-11-28"
13
13
  s.description = "Line based local source code search engine & grep-command & web-app."
14
14
  s.email = "ongaeshi0621@gmail.com"
15
15
  s.executables = ["gmilk", "milk"]
@@ -53,6 +53,8 @@ Gem::Specification.new do |s|
53
53
  "lib/milkode/cdweb/lib/search_fuzzy_gotoline.rb",
54
54
  "lib/milkode/cdweb/lib/search_gotoline.rb",
55
55
  "lib/milkode/cdweb/lib/web_setting.rb",
56
+ "lib/milkode/cdweb/locales/en.yml",
57
+ "lib/milkode/cdweb/locales/ja.yml",
56
58
  "lib/milkode/cdweb/public/css/auth-buttons.css",
57
59
  "lib/milkode/cdweb/public/css/auth-icons.png",
58
60
  "lib/milkode/cdweb/public/css/bootstrap-responsive.min.css",
@@ -217,6 +219,7 @@ Gem::Specification.new do |s|
217
219
  s.add_runtime_dependency(%q<haml>, [">= 3.1.2"])
218
220
  s.add_runtime_dependency(%q<sass>, [">= 3.1.3"])
219
221
  s.add_runtime_dependency(%q<thor>, [">= 0.18.1"])
222
+ s.add_runtime_dependency(%q<i18n>, ["~> 0.6.5"])
220
223
  s.add_development_dependency(%q<bundler>, [">= 0"])
221
224
  s.add_development_dependency(%q<jeweler>, [">= 0"])
222
225
  s.add_development_dependency(%q<rack-test>, [">= 0"])
@@ -234,6 +237,7 @@ Gem::Specification.new do |s|
234
237
  s.add_dependency(%q<haml>, [">= 3.1.2"])
235
238
  s.add_dependency(%q<sass>, [">= 3.1.3"])
236
239
  s.add_dependency(%q<thor>, [">= 0.18.1"])
240
+ s.add_dependency(%q<i18n>, ["~> 0.6.5"])
237
241
  s.add_dependency(%q<bundler>, [">= 0"])
238
242
  s.add_dependency(%q<jeweler>, [">= 0"])
239
243
  s.add_dependency(%q<rack-test>, [">= 0"])
@@ -252,6 +256,7 @@ Gem::Specification.new do |s|
252
256
  s.add_dependency(%q<haml>, [">= 3.1.2"])
253
257
  s.add_dependency(%q<sass>, [">= 3.1.3"])
254
258
  s.add_dependency(%q<thor>, [">= 0.18.1"])
259
+ s.add_dependency(%q<i18n>, ["~> 0.6.5"])
255
260
  s.add_dependency(%q<bundler>, [">= 0"])
256
261
  s.add_dependency(%q<jeweler>, [">= 0"])
257
262
  s.add_dependency(%q<rack-test>, [">= 0"])
data/test/test_cli.rb CHANGED
@@ -23,6 +23,14 @@ class TestCLI < Test::Unit::TestCase
23
23
  @work.teardown
24
24
  end
25
25
 
26
+ def test_add
27
+ # system("type git")
28
+ command("add")
29
+ assert_not_match /error/, command("add https://github.com/ongaeshi/mini-repo-git.git")
30
+ assert_not_match /error/, command("add https://github.com/ongaeshi/mini-repo-git.git -n mrg-develop -b develop")
31
+ assert_match /error/, command("add https://github.com/ongaeshi/mini-repo-git.git -n mrg-developa -b developa") # not found branch
32
+ end
33
+
26
34
  def test_grep
27
35
  command("grep")
28
36
  command("grep not_found")
data/test/test_util.rb CHANGED
@@ -101,6 +101,7 @@ class TestUtil < Test::Unit::TestCase
101
101
  assert_equal true, Milkode::Util::git_url?('git://github.com/ongaeshi/milkode.git')
102
102
  assert_equal true, Milkode::Util::git_url?('git@github.com:ongaeshi/milkode.git')
103
103
  assert_equal true, Milkode::Util::git_url?('ssh:foo@bar/baz.git')
104
+ assert_equal true, Milkode::Util::git_url?('https://github.com/ongaeshi/milkode.git')
104
105
  end
105
106
 
106
107
  def test_svn_url?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: milkode
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-28 00:00:00.000000000 Z
12
+ date: 2013-11-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: termcolor
@@ -193,6 +193,22 @@ dependencies:
193
193
  - - ! '>='
194
194
  - !ruby/object:Gem::Version
195
195
  version: 0.18.1
196
+ - !ruby/object:Gem::Dependency
197
+ name: i18n
198
+ requirement: !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - ~>
202
+ - !ruby/object:Gem::Version
203
+ version: 0.6.5
204
+ type: :runtime
205
+ prerelease: false
206
+ version_requirements: !ruby/object:Gem::Requirement
207
+ none: false
208
+ requirements:
209
+ - - ~>
210
+ - !ruby/object:Gem::Version
211
+ version: 0.6.5
196
212
  - !ruby/object:Gem::Dependency
197
213
  name: bundler
198
214
  requirement: !ruby/object:Gem::Requirement
@@ -318,6 +334,8 @@ files:
318
334
  - lib/milkode/cdweb/lib/search_fuzzy_gotoline.rb
319
335
  - lib/milkode/cdweb/lib/search_gotoline.rb
320
336
  - lib/milkode/cdweb/lib/web_setting.rb
337
+ - lib/milkode/cdweb/locales/en.yml
338
+ - lib/milkode/cdweb/locales/ja.yml
321
339
  - lib/milkode/cdweb/public/css/auth-buttons.css
322
340
  - lib/milkode/cdweb/public/css/auth-icons.png
323
341
  - lib/milkode/cdweb/public/css/bootstrap-responsive.min.css