mamemose 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +4 -0
  2. data/lib/mamemose.rb +163 -111
  3. data/lib/mamemose/version.rb +1 -1
  4. metadata +2 -2
data/README.md CHANGED
@@ -85,6 +85,10 @@ http://localhost:PORT/
85
85
  - ポート。 http://localhost:PORT/ にアクセス。デフォルトは 20000
86
86
  - `MARKDOWN_PATTERN`
87
87
  - Markdown ドキュメントと見なすファイルパターンを正規表現で。デフォルトは `/\.(md|markdown)$/`
88
+ - `INDEX_PATTERN`
89
+ - 一覧ページ表示時に自動的に読み込むファイルパターンを正規表現で。
90
+ これにマッチするファイルは1つのディレクトリに複数置かないほうがいいです。
91
+ デフォルトは `/^README/`
88
92
  - `RECENT_NUM`
89
93
  - 「最近更新したファイル」を表示する数。デフォルトは 10
90
94
  - `RECENT_PATTERN`
data/lib/mamemose.rb CHANGED
@@ -18,6 +18,7 @@ IGNORE_FILES = ['.DS_Store','.AppleDouble','.LSOverride','Icon',/^\./,/~$/,
18
18
  '.Spotlight-V100','.Trashes','Thumbs.db','ehthumbs.db',
19
19
  'Desktop.ini','$RECYCLE.BIN',/^#/,'MathJax','syntaxhighlighter'] if !defined?(IGNORE_FILES)
20
20
  MARKDOWN_PATTERN = /\.(md|markdown)$/ if !defined?(MARKDOWN_PATTERN)
21
+ INDEX_PATTERN = /^README/i
21
22
  CUSTOM_HEADER = '' if !defined?(CUSTOM_HEADER)
22
23
  CUSTOM_BODY = '' if !defined?(CUSTOM_BODY)
23
24
  CUSTOM_FOOTER = '' if !defined?(CUSTOM_FOOTER)
@@ -40,117 +41,15 @@ class Mamemose::Server
40
41
  res['Cache-Control'] = 'no-cache, no-store, must-revalidate'
41
42
  res['Pragma'] = 'no-cache'
42
43
  res['Expires'] = '0'
43
- if req.path =~ /^\/search/
44
- query = req.query
45
- path = fullpath(query["path"])
46
- q = URI.decode(query["q"])
47
- q = q.force_encoding('utf-8') if q.respond_to?(:force_encoding)
48
-
49
- found = {}
50
- Find.find(path) do |file|
51
- Find.prune if ignore?(file)
52
- dir = File::dirname(file)
53
- found[dir] = [] if !found[dir]
54
- if markdown?(file)
55
- open(file) do |f|
56
- c = f.read + "\n" + file
57
- found[dir] << [get_title(file,c), uri(file)] if !q.split(' ').map{|s| /#{s}/mi =~ c }.include?(nil)
58
- end
59
- elsif !q.split(' ').map{|s| /#{s}/ =~ File.basename(file)}.include?(nil)
60
- found[dir] << [get_title(file),uri(file)]
61
- end
62
- end
63
-
64
- title = "Search #{q} in #{showpath(query['path'])}"
65
- title = title.force_encoding('utf-8') if title.respond_to?(:force_encoding)
66
- body = title + "\n====\n"
67
- found.reject{|key, value| value == []}.sort.each do |key, value|
68
- body += "\n### in <a href='#{uri(key)}'>#{escape(uri(key))}</a>\n"
69
- value.each do |v|
70
- body += link_list(v[0], v[1])
71
- end
72
- end
73
-
74
- res.body = header_html(title, uri(path), q) + markdown(body) + footer_html
75
- res.content_type = CONTENT_TYPE
76
44
 
45
+ if req.path =~ /^\/search/
46
+ res = req_search(req, res)
47
+ elsif File.directory?(fullpath(req.path)) then
48
+ res = req_index(req, res)
49
+ elsif File.exists?(fullpath(req.path))
50
+ res = req_file(req, res)
77
51
  else
78
-
79
- filename = fullpath(req.path)
80
-
81
- if File.directory?(filename) then
82
- title = "Index of #{showpath(req.path)}"
83
- body = title + "\n====\n"
84
-
85
- recent = []
86
- dirs = []
87
- markdowns = []
88
- files = []
89
-
90
- if RECENT_NUM > 0 then
91
- Find.find(filename) do |file|
92
- Find.prune if ignore?(file)
93
- recent << file if File.file?(file) && file =~ RECENT_PATTERN
94
- end
95
- recent = recent.sort_by{|file| File.mtime(file)}.reverse.slice(0,RECENT_NUM)
96
- recent = recent.map{|file|
97
- if markdown?(file) then
98
- [get_title(file, open(file).read), uri(file)]
99
- else
100
- [escaped_basename(file), uri(file)]
101
- end
102
- }
103
- else
104
- recent = []
105
- end
106
-
107
- Dir.entries(filename).each do |i|
108
- next if ignore?(i)
109
- link = uri(File.join(filename, i))
110
- if File.directory?(fullpath(link)) then
111
- dirs << [escaped_basename(link) + File::SEPARATOR, link]
112
- elsif markdown?(link)
113
- File.open(fullpath(link)) do |f|
114
- markdowns << [get_title(link, f.read), link]
115
- end
116
- else
117
- files << [escaped_basename(link), link]
118
- end
119
- end
120
-
121
- body += "\nRecent:\n---\n" if RECENT_NUM > 0
122
- recent.each {|i| body += link_list(i[0], i[1])}
123
-
124
- body += "\nDirectories:\n----\n"
125
- dirs.each {|i| body += link_list(i[0], i[1])}
126
-
127
- body += "\nMarkdown documents:\n----\n"
128
- markdowns.each {|i| body += link_list(i[0], i[1])}
129
-
130
- body += "\nOther files:\n----\n"
131
- files.each {|i| body += link_list(i[0], i[1])}
132
-
133
- res.body = header_html(title, req.path) + markdown(body) + footer_html
134
- res.content_type = CONTENT_TYPE
135
-
136
- elsif File.exists?(filename)
137
- open(filename) do |file|
138
- if markdown?(req.path)
139
- str = file.read
140
- title = get_title(filename, str)
141
- res.body = header_html(title, req.path) + markdown(str) + footer_html(fullpath(req.path))
142
- res.content_type = CONTENT_TYPE
143
- else
144
- res.body = file.read
145
- res.content_type = WEBrick::HTTPUtils.mime_type(req.path, WEBrick::HTTPUtils::DefaultMimeTypes)
146
- res.content_length = File.stat(filename).size
147
- end
148
- end
149
-
150
- else
151
- res.status = WEBrick::HTTPStatus::RC_NOT_FOUND
152
- end
153
-
52
+ res.status = WEBrick::HTTPStatus::RC_NOT_FOUND
154
53
  end
155
54
  end
156
55
 
@@ -265,6 +164,11 @@ blockquote {
265
164
  padding: 0.3em 0;
266
165
  background-color: #f3fff3;
267
166
  }
167
+ hr {
168
+ height: 1px;
169
+ border: none;
170
+ border-top: 1px solid black;
171
+ }
268
172
  --></style>
269
173
  <script>
270
174
  function copy(text) {
@@ -297,7 +201,15 @@ HTML
297
201
  end
298
202
 
299
203
  def footer_html(filepath=nil)
300
- updated = filepath ? "Last Updated: " + File.mtime(filepath).strftime("%Y-%m-%d %H:%M:%S") + " / " : ""
204
+ if filepath
205
+ updated = File.basename(filepath)\
206
+ + " [#{filesize(filepath)}]"\
207
+ + " / Last Updated: "\
208
+ + File.mtime(filepath).strftime("%Y-%m-%d %H:%M:%S")\
209
+ + " / "
210
+ else
211
+ updated = ""
212
+ end
301
213
  html = <<HTML
302
214
  #{CUSTOM_FOOTER}
303
215
  <footer>
@@ -310,6 +222,133 @@ HTML
310
222
  return html
311
223
  end
312
224
 
225
+ def req_search(req, res)
226
+ query = req.query
227
+ path = fullpath(query["path"])
228
+ q = URI.decode(query["q"])
229
+ q = q.force_encoding('utf-8') if q.respond_to?(:force_encoding)
230
+
231
+ found = find(path, q)
232
+
233
+ title = "Search #{q} in #{showpath(query['path'])}"
234
+ title = title.force_encoding('utf-8') if title.respond_to?(:force_encoding)
235
+ body = title + "\n====\n"
236
+ found.reject{|key, value| value == []}.sort.each do |key, value|
237
+ body += "\n### in <a href='#{uri(key)}'>#{escape(uri(key))}</a>\n"
238
+ value.each {|v| body += link_list(v[0], v[1])}
239
+ end
240
+
241
+ res.body = header_html(title, uri(path), q) + markdown(body) + footer_html
242
+ res.content_type = CONTENT_TYPE
243
+ return res
244
+ end
245
+
246
+ def req_index(req, res)
247
+ directory = fullpath(req.path)
248
+ title = "Index of #{showpath(req.path)}"
249
+ body = title + "\n====\n"
250
+
251
+ recent = recent_files(directory)
252
+ fs = directory_files(directory)
253
+
254
+ body += "\nRecent:\n---\n" if RECENT_NUM > 0
255
+ recent.each {|i| body += link_list(i[0], i[1])}
256
+
257
+ body += "\nDirectories:\n----\n"
258
+ fs[:dirs].each {|i| body += link_list(i[0], i[1])}
259
+
260
+ body += "\nMarkdown documents:\n----\n"
261
+ fs[:markdowns].each {|i| body += link_list(i[0], i[1])}
262
+
263
+ body += "\nOther files:\n----\n"
264
+ fs[:others].each {|i| body += link_list(i[0], i[1])}
265
+
266
+ if index = indexfile(directory)
267
+ body += "\n\n"
268
+ body += File.read(index)
269
+ end
270
+
271
+ res.body = header_html(title, req.path) + markdown(body) + footer_html(index)
272
+ res.content_type = CONTENT_TYPE
273
+ return res
274
+ end
275
+
276
+ def req_file(req, res)
277
+ filename = fullpath(req.path)
278
+ open(filename) do |file|
279
+ if markdown?(req.path)
280
+ str = file.read
281
+ title = get_title(filename, str)
282
+ res.body = header_html(title, req.path) + markdown(str) + footer_html(fullpath(req.path))
283
+ res.content_type = CONTENT_TYPE
284
+ else
285
+ res.body = file.read
286
+ res.content_type = WEBrick::HTTPUtils.mime_type(req.path, WEBrick::HTTPUtils::DefaultMimeTypes)
287
+ res.content_length = File.stat(filename).size
288
+ end
289
+ end
290
+ return res
291
+ end
292
+
293
+ def find(directory, query)
294
+ found = {}
295
+ Find.find(directory) do |file|
296
+ Find.prune if ignore?(file)
297
+ dir = File::dirname(file)
298
+ found[dir] = [] if !found[dir]
299
+ if markdown?(file)
300
+ open(file) do |f|
301
+ c = f.read + "\n" + file
302
+ found[dir] << [get_title(file,c), uri(file)] if !query.split(' ').map{|s| /#{s}/mi =~ c }.include?(nil)
303
+ end
304
+ elsif !query.split(' ').map{|s| /#{s}/ =~ File.basename(file)}.include?(nil)
305
+ found[dir] << [get_title(file),uri(file)]
306
+ end
307
+ end
308
+ return found
309
+ end
310
+
311
+ def recent_files(directory)
312
+ recent = []
313
+ if RECENT_NUM > 0 then
314
+ Find.find(directory) do |file|
315
+ Find.prune if ignore?(file)
316
+ recent << file if File.file?(file) && file =~ RECENT_PATTERN
317
+ end
318
+ recent = recent.sort_by{|file| File.mtime(file)}.reverse.slice(0,RECENT_NUM)
319
+ recent = recent.map{|file|
320
+ if markdown?(file) then
321
+ [get_title(file, open(file).read), uri(file)]
322
+ else
323
+ [escaped_basename(file), uri(file)]
324
+ end
325
+ }
326
+ else
327
+ recent = []
328
+ end
329
+ return recent
330
+ end
331
+
332
+ def directory_files(directory)
333
+ dirs = []
334
+ markdowns = []
335
+ others = []
336
+ Dir.entries(directory).each do |i|
337
+ next if ignore?(i)
338
+ link = uri(File.join(directory, i))
339
+ if File.directory?(fullpath(link)) then
340
+ dirs << [escaped_basename(link) + File::SEPARATOR, link]
341
+ elsif markdown?(link)
342
+ File.open(fullpath(link)) do |f|
343
+ markdowns << [get_title(link, f.read), link]
344
+ end
345
+ else
346
+ others << [escaped_basename(link), link]
347
+ end
348
+ end
349
+ return {:dirs=>dirs, :markdowns=>markdowns, :others=>others}
350
+ end
351
+
313
352
  # returns escaped characters so that the markdown parser doesn't interpret it has special meaning.
314
353
  def escape(text)
315
354
  return text.gsub(/[\`*_{}\[\]()#+\-.!]/, "\\\\\\0")
@@ -343,10 +382,14 @@ HTML
343
382
 
344
383
  def link_list(title, link)
345
384
  file = fullpath(link)
346
- str = File.file?(file) ? sprintf("%.1fKB", File.size(file) / 1024.0) : "dir"
385
+ str = filesize(file)
347
386
  return "- [#{title}](#{link}) <a class='filename' href=\"javascript:copy('#{docpath(link)}');\">[#{escaped_basename(link)}, #{str}]</a>\n"
348
387
  end
349
388
 
389
+ def filesize(file)
390
+ File.file?(file) ? sprintf("%.1fKB", File.size(file) / 1024.0) : "dir"
391
+ end
392
+
350
393
  def markdown?(file)
351
394
  return file =~ MARKDOWN_PATTERN
352
395
  end
@@ -366,6 +409,15 @@ HTML
366
409
  return title =~ /^\s*$/ ? escaped_basename(filename) : title
367
410
  end
368
411
 
412
+ def indexfile(dir)
413
+ Dir.entries(dir).each do |f|
414
+ if f =~ INDEX_PATTERN && markdown?(f)
415
+ return dir + File::SEPARATOR + f
416
+ end
417
+ end
418
+ return nil
419
+ end
420
+
369
421
  def markdown(text)
370
422
  markdown = Redcarpet::Markdown.new(HTMLwithSyntaxHighlighter,
371
423
  {:strikethrough => true,
@@ -1,3 +1,3 @@
1
1
  module Mamemose
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mamemose
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.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: 2012-12-17 00:00:00.000000000 Z
12
+ date: 2012-12-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redcarpet