milkode 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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