mamemose 0.1.4 → 0.2.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.
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