directory_listing 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/LICENSE +13 -0
- data/README.md +89 -0
- data/Rakefile +1 -0
- data/directory_listing.gemspec +22 -0
- data/lib/sinatra/directory_listing/layout.rb +32 -0
- data/lib/sinatra/directory_listing/resource.rb +140 -0
- data/lib/sinatra/directory_listing/version.rb +3 -0
- data/lib/sinatra/directory_listing.rb +112 -126
- metadata +87 -58
- checksums.yaml +0 -7
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
### directory_listing: easy, CSS-styled, Apache-like directory listings for Sinatra.
|
2
|
+
|
3
|
+
### Build from source:
|
4
|
+
|
5
|
+
```bash
|
6
|
+
gem build directory_listing.gemspec
|
7
|
+
sudo gem install ./directory_listing-x.x.x.gem
|
8
|
+
```
|
9
|
+
|
10
|
+
### Usage:
|
11
|
+
|
12
|
+
```list()``` will return HTML, so the following is a complete Sinatra app that will provide a directory listing of whatever path you navigate to and let you view any file that is served directly:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'sinatra'
|
16
|
+
require 'sinatra/directory_listing'
|
17
|
+
|
18
|
+
get '*' do |path|
|
19
|
+
if File.exist?(File.join(settings.public_folder, path))
|
20
|
+
if File.directory?(File.join(settings.public_folder, path))
|
21
|
+
list()
|
22
|
+
else
|
23
|
+
send_file File.join(settings.public_folder, path)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
not_found
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
not_found do
|
31
|
+
'Try again.'
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
### Options:
|
36
|
+
|
37
|
+
Options are passed in a hash:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
list({
|
41
|
+
:stylesheet => "stylesheets/styles.css",
|
42
|
+
:readme => "<a>Welcome!</a>"
|
43
|
+
})
|
44
|
+
```
|
45
|
+
|
46
|
+
Available options:
|
47
|
+
|
48
|
+
- ```stylesheet``` - a stylesheet that will be added to the <head> of the generated directory listing
|
49
|
+
- ```readme``` - an HTML string that will be appended at the footer of the generated directory listing
|
50
|
+
- ```should_list_invisibles``` - whether the directory listing should include invisibles (dotfiles) - true or false, defaults to false
|
51
|
+
- ```last_modified_format``` - [format](http://www.ruby-doc.org/core-2.0/Time.html) for last modified date - defaults to ```%Y-%m-%d %H:%M:%S```
|
52
|
+
- ```filename_truncate_length``` - (integer) length to truncate file names to - defaults to 40
|
53
|
+
|
54
|
+
### Styling:
|
55
|
+
|
56
|
+
It's pretty easy to figure out how to style ```directory_listing``` by looking at the source, but here are some gotchas:
|
57
|
+
|
58
|
+
- Every item listed is a ```<td>``` element in a table. Directories will have a class of ```dir``` and regular files will have a class of ```file```.
|
59
|
+
- You can style the "File" column with this CSS:
|
60
|
+
|
61
|
+
```css
|
62
|
+
table tr > td:first-child {
|
63
|
+
text-align: left;
|
64
|
+
}
|
65
|
+
```
|
66
|
+
|
67
|
+
- "Last modified" column:
|
68
|
+
|
69
|
+
```css
|
70
|
+
table tr > td:first-child + td {
|
71
|
+
text-align: left;
|
72
|
+
}
|
73
|
+
```
|
74
|
+
|
75
|
+
- "Size" column:
|
76
|
+
|
77
|
+
```css
|
78
|
+
table tr > td:first-child + td + td {
|
79
|
+
text-align: left;
|
80
|
+
}
|
81
|
+
```
|
82
|
+
|
83
|
+
### Contributing:
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (```git checkout -b my-new-feature```)
|
87
|
+
3. Commit your changes (```git commit -am 'Add some feature'```)
|
88
|
+
4. Push to the branch (```git push origin my-new-feature```)
|
89
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.join(Dir.pwd, 'lib/sinatra/directory_listing.rb')
|
2
|
+
require File.join(Dir.pwd, 'lib/sinatra/directory_listing/version.rb')
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'directory_listing'
|
6
|
+
s.version = Directory_listing::VERSION
|
7
|
+
s.date = Time.now.strftime("%Y-%m-%d")
|
8
|
+
s.summary = "Easy, CSS-styled, Apache-like directory listings for Sinatra."
|
9
|
+
s.description = "A Sinatra extension for generating easy, CSS-styled, Apache-like directory listings."
|
10
|
+
s.authors = ["Richard Myers"]
|
11
|
+
s.email = 'rick.myers@me.com'
|
12
|
+
s.license = 'WTFPL'
|
13
|
+
s.files = `git ls-files`.split($/)
|
14
|
+
s.homepage = 'https://rubygems.org/gems/directory_listing'
|
15
|
+
|
16
|
+
s.add_dependency 'filesize', '>=0.0.2'
|
17
|
+
s.add_dependency 'truncate', '>=0.0.4'
|
18
|
+
|
19
|
+
s.add_development_dependency "bundler", "~> 1.3"
|
20
|
+
s.add_development_dependency "rake"
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module Directory_listing
|
3
|
+
|
4
|
+
LAYOUT = <<-EOF
|
5
|
+
<html>
|
6
|
+
<head>
|
7
|
+
<title>Index of <%= $current_page %>, sorted <%= $sort_item_display %> <%= $sort_direction_display %></title>
|
8
|
+
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
9
|
+
<%= $stylesheet %>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<h1>Index of <%= $current_page %></h1>
|
13
|
+
<%= $back_to_link %>
|
14
|
+
<br><br>
|
15
|
+
|
16
|
+
<table>
|
17
|
+
<tr>
|
18
|
+
<th><a href='<%= $file_sort_link %>'>File</a></th>
|
19
|
+
<th><a href='<%= $mtime_sort_link %>'>Last modified</a></th>
|
20
|
+
<th><a href='<%= $size_sort_link %>'>Size</a></th>
|
21
|
+
</tr>
|
22
|
+
<%= $files_html %>
|
23
|
+
</table>
|
24
|
+
|
25
|
+
<br>
|
26
|
+
<a><%= $readme if $readme %></a>
|
27
|
+
</body>
|
28
|
+
</html>
|
29
|
+
EOF
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
class Resource
|
2
|
+
|
3
|
+
##
|
4
|
+
# Class definition for a single resource to be listed.
|
5
|
+
# Each resource object has accessors for its file name, regular name,
|
6
|
+
# size and mtime, as well as those components wrapped in html.
|
7
|
+
|
8
|
+
attr_accessor :file, :name_html, :mtime, :mtime_html, :size, :size_html
|
9
|
+
|
10
|
+
def initialize(file)
|
11
|
+
@file = file
|
12
|
+
@name_html = set_name(file)
|
13
|
+
@mtime, @mtime_html = set_mtime(file)
|
14
|
+
@size, @size_html = set_size(file)
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Get the mtime for a file.
|
19
|
+
|
20
|
+
def set_mtime(file)
|
21
|
+
f = File.join(File.join($public_folder, URI.unescape($request_path)), file)
|
22
|
+
html = "\t<td>#{File.mtime(f).strftime($last_modified_format)}</td>"
|
23
|
+
|
24
|
+
##
|
25
|
+
# Return the mtime as a Time object so it can be sorted.
|
26
|
+
|
27
|
+
return [File.mtime(f), html]
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Get the size for a file.
|
32
|
+
|
33
|
+
def set_size(file)
|
34
|
+
html = ""
|
35
|
+
size = ''
|
36
|
+
f = File.join(File.join($public_folder, URI.unescape($request_path)), file)
|
37
|
+
if File.directory?(f)
|
38
|
+
size = 0
|
39
|
+
html = "\t<td>-</td>"
|
40
|
+
else
|
41
|
+
size = File.stat(f).size
|
42
|
+
converted = Filesize.from("#{File.stat(f).size} B").pretty
|
43
|
+
html = "\t<td>#{converted}</td>"
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Return the mtime as a Time object so it can be sorted.
|
48
|
+
|
49
|
+
return [size, html]
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Get the name of the file and its link.
|
54
|
+
|
55
|
+
def set_name(file)
|
56
|
+
|
57
|
+
##
|
58
|
+
# Make sure we're working with an unescaped file name and truncate it.
|
59
|
+
# URI.unescape seems to work best to decode uris.
|
60
|
+
|
61
|
+
file = URI.unescape(file)
|
62
|
+
file_truncated = file.truncate($filename_truncate_length, '...')
|
63
|
+
|
64
|
+
##
|
65
|
+
# If the requested resource is in the root public directory, the link is
|
66
|
+
# just the resource itself without the public directory path as well.
|
67
|
+
|
68
|
+
requested = Pathname.new(URI.unescape($request_path)).cleanpath
|
69
|
+
pub_folder = Pathname.new($public_folder).cleanpath
|
70
|
+
if requested.eql?(pub_folder)
|
71
|
+
link = file
|
72
|
+
else
|
73
|
+
link = File.join($request_path, file)
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Add a class of "dir" to directories and "file" to files.
|
78
|
+
|
79
|
+
html = ""
|
80
|
+
if File.directory?(File.join($public_folder, link))
|
81
|
+
html << "\t<td class='dir'>"
|
82
|
+
|
83
|
+
##
|
84
|
+
# Append the sorting information if the current directory is sorted
|
85
|
+
|
86
|
+
if $request_params["sortby"] && $request_params["direction"]
|
87
|
+
link << "?sortby=" + $request_params["sortby"] + "&direction=" + $request_params["direction"]
|
88
|
+
end
|
89
|
+
else
|
90
|
+
html << "\t<td class='file'>"
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Append the rest of the html.
|
95
|
+
#
|
96
|
+
# I haven't found a URI escaping library that will handle this
|
97
|
+
# gracefully, so for now, we're going to just take care of spaces and
|
98
|
+
# apostrophes ourselves.
|
99
|
+
|
100
|
+
link = link.gsub(" ", "%20").gsub("'", "%27")
|
101
|
+
|
102
|
+
html << "<a href='#{link}'>#{file_truncated}</a></td>"
|
103
|
+
|
104
|
+
return html
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Generate html for a resource.
|
109
|
+
|
110
|
+
def wrap
|
111
|
+
html = ""
|
112
|
+
if $should_list_invisibles == true
|
113
|
+
html << "\n\t<tr>
|
114
|
+
#{@name_html}
|
115
|
+
#{@mtime_html}
|
116
|
+
#{@size_html}
|
117
|
+
\t</tr>"
|
118
|
+
else
|
119
|
+
if @file[0] != "."
|
120
|
+
html << "\n\t<tr>
|
121
|
+
#{@name_html}
|
122
|
+
#{@mtime_html}
|
123
|
+
#{@size_html}
|
124
|
+
\t</tr>"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
html
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# Sort an array of resources by name, mtime, or size.
|
132
|
+
# Direction should be "ascending" or "descending"
|
133
|
+
|
134
|
+
def self.sort(resource_array, sortby, direction)
|
135
|
+
new_array = resource_array.sort_by {|a| a.send(sortby)}
|
136
|
+
new_array.reverse! if direction == "descending"
|
137
|
+
new_array
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -90,130 +90,18 @@ require 'erb'
|
|
90
90
|
module Sinatra
|
91
91
|
module Directory_listing
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
def template
|
99
|
-
"<html>
|
100
|
-
<head>
|
101
|
-
<title>Index of <%= $current_page %></title>
|
102
|
-
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
103
|
-
<%= $stylesheet %>
|
104
|
-
</head>
|
105
|
-
<body>
|
106
|
-
<h1>Index of <%= $current_page %></h1>
|
107
|
-
<%= $back_to_link %>
|
108
|
-
<br><br>
|
109
|
-
|
110
|
-
<table>
|
111
|
-
<tr>
|
112
|
-
<th>File</th>
|
113
|
-
<th>Last modified</th>
|
114
|
-
<th>Size</th>
|
115
|
-
</tr>
|
116
|
-
<%= $files_html %>
|
117
|
-
</table>
|
118
|
-
|
119
|
-
<br>
|
120
|
-
<a><%= $readme if $readme %></a>
|
121
|
-
</body>
|
122
|
-
</html>"
|
123
|
-
end
|
124
|
-
|
125
|
-
##
|
126
|
-
# Get the mtime for a file.
|
127
|
-
|
128
|
-
def m_time(file)
|
129
|
-
f = File.join(File.join(settings.public_folder, URI.unescape(request.fullpath)), file)
|
130
|
-
"\t<td>#{File.mtime(f).strftime($last_modified_format)}</td>"
|
131
|
-
end
|
132
|
-
|
133
|
-
##
|
134
|
-
# Get the size for a file.
|
135
|
-
|
136
|
-
def size(file)
|
137
|
-
f = File.join(File.join(settings.public_folder, URI.unescape(request.fullpath)), file)
|
138
|
-
if File.directory?(f)
|
139
|
-
"\t<td>-</td>"
|
140
|
-
else
|
141
|
-
size = Filesize.from("#{File.stat(f).size} B").pretty
|
142
|
-
"\t<td>#{size}</td>"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
93
|
+
require_relative 'directory_listing/version.rb'
|
94
|
+
require_relative 'directory_listing/layout.rb'
|
95
|
+
require_relative 'directory_listing/resource.rb'
|
96
|
+
|
146
97
|
##
|
147
|
-
#
|
148
|
-
|
149
|
-
def name(file)
|
150
|
-
|
151
|
-
##
|
152
|
-
# Make sure we're working with an unescaped file name and truncate it.
|
153
|
-
# URI.unescape seems to work best to decode uris.
|
154
|
-
|
155
|
-
file = URI.unescape(file)
|
156
|
-
file_truncated = file.truncate($filename_truncate_length, '...')
|
157
|
-
|
158
|
-
##
|
159
|
-
# If the requested resource is in the root public directory, the link is
|
160
|
-
# just the resource itself without the public directory path as well.
|
161
|
-
|
162
|
-
requested = Pathname.new(URI.unescape(request.path)).cleanpath
|
163
|
-
public_folder = Pathname.new(settings.public_folder).cleanpath
|
164
|
-
if requested.eql?(public_folder)
|
165
|
-
link = file
|
166
|
-
else
|
167
|
-
link = File.join(request.fullpath, file)
|
168
|
-
end
|
169
|
-
|
170
|
-
##
|
171
|
-
# Add a class of "dir" to directories and "file" to files.
|
98
|
+
# Generate the page.
|
172
99
|
|
173
|
-
|
174
|
-
if File.directory?(File.join(settings.public_folder, link))
|
175
|
-
html << "\t<td class='dir'>"
|
176
|
-
else
|
177
|
-
html << "\t<td class='file'>"
|
178
|
-
end
|
100
|
+
def list(o={})
|
179
101
|
|
180
102
|
##
|
181
|
-
#
|
182
|
-
#
|
183
|
-
# I haven't found a URI escaping library that will handle this
|
184
|
-
# gracefully, so for now, we're going to just take care of spaces and
|
185
|
-
# apostrophes ourselves.
|
103
|
+
# Set default options.
|
186
104
|
|
187
|
-
link = link.gsub(" ", "%20").gsub("'", "%27")
|
188
|
-
html << "<a href='#{link}'>#{file_truncated}</a></td>"
|
189
|
-
html
|
190
|
-
end
|
191
|
-
|
192
|
-
##
|
193
|
-
# Generate a single row of data for a file.
|
194
|
-
|
195
|
-
def wrap(file)
|
196
|
-
html = ""
|
197
|
-
if $should_list_invisibles == true
|
198
|
-
html << "\n\t<tr>
|
199
|
-
#{self.name(file)}
|
200
|
-
#{self.m_time(file)}
|
201
|
-
#{self.size(file)}\n\t</tr>"
|
202
|
-
else
|
203
|
-
if file[0] != "."
|
204
|
-
html << "\n\t<tr>
|
205
|
-
#{self.name(file)}
|
206
|
-
#{self.m_time(file)}
|
207
|
-
#{self.size(file)}\n\t</tr>"
|
208
|
-
end
|
209
|
-
end
|
210
|
-
html
|
211
|
-
end
|
212
|
-
|
213
|
-
##
|
214
|
-
# Generate the page.
|
215
|
-
|
216
|
-
def list(o={})
|
217
105
|
options = {
|
218
106
|
:should_list_invisibles => false,
|
219
107
|
:last_modified_format => "%Y-%m-%d %H:%M:%S",
|
@@ -226,22 +114,49 @@ module Sinatra
|
|
226
114
|
$last_modified_format = options[:last_modified_format]
|
227
115
|
$filename_truncate_length = options[:filename_truncate_length]
|
228
116
|
|
117
|
+
##
|
118
|
+
# Get the public folder, request path, and parameters and
|
119
|
+
# store in globals to be used by the Resource class.
|
120
|
+
|
121
|
+
$public_folder = settings.public_folder
|
122
|
+
$request_path = request.path
|
123
|
+
$request_params = request.params
|
124
|
+
|
229
125
|
##
|
230
126
|
# Start generating strings to be injected into the erb template
|
231
127
|
|
232
128
|
$current_page = URI.unescape(request.path)
|
233
129
|
$readme = options[:readme] if options[:readme]
|
234
|
-
|
130
|
+
if options[:stylesheet]
|
131
|
+
$stylesheet = "<link rel='stylesheet' type='text/css' href='/#{options[:stylesheet].sub(/^[\/]*/,"")}'>"
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Generate the "back to" link
|
136
|
+
# Append the sorting information if the current directory is sorted.
|
235
137
|
|
236
138
|
if URI.unescape(request.path) != "/"
|
237
|
-
|
139
|
+
back_link = Pathname.new(URI.unescape(request.path)).parent
|
140
|
+
if $request_params["sortby"] && $request_params["direction"]
|
141
|
+
back_link = back_link.to_s + "?sortby=" + $request_params["sortby"] + "&direction=" + $request_params["direction"]
|
142
|
+
end
|
143
|
+
$back_to_link = "<a href='#{back_link}'>← Parent directory</a>"
|
238
144
|
else
|
239
145
|
$back_to_link = "<a>Root directory</a>"
|
240
146
|
end
|
241
147
|
|
242
|
-
|
148
|
+
##
|
149
|
+
# Get an array of files to be listed.
|
150
|
+
|
243
151
|
files = Array.new
|
244
|
-
Dir.foreach(File.join(settings.public_folder, URI.unescape(request.path))
|
152
|
+
Dir.foreach(File.join(settings.public_folder, URI.unescape(request.path))) do |file|
|
153
|
+
files.push(file)
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# If the only thing in the array are invisible files, display a "No files" listing.
|
158
|
+
|
159
|
+
$files_html = ""
|
245
160
|
if files == [".", ".."]
|
246
161
|
$files_html << "
|
247
162
|
<tr>
|
@@ -250,15 +165,86 @@ module Sinatra
|
|
250
165
|
<th>-</th>
|
251
166
|
</tr>"
|
252
167
|
else
|
253
|
-
|
254
|
-
|
168
|
+
|
169
|
+
##
|
170
|
+
# Otherwise, create an array of Resources:
|
171
|
+
|
172
|
+
resources = Array.new
|
173
|
+
Dir.foreach(File.join(settings.public_folder, URI.unescape(request.path))) do |resource|
|
174
|
+
resources.push(Resource.new(resource))
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Get the sortby and direction parameters ("file" and "ascending", by
|
179
|
+
# default).
|
180
|
+
|
181
|
+
$sort_item = "file"
|
182
|
+
$sort_direction = "ascending"
|
183
|
+
$sort_item = $request_params["sortby"] if $request_params["sortby"]
|
184
|
+
$sort_direction = $request_params["direction"] if $request_params["direction"]
|
185
|
+
|
186
|
+
##
|
187
|
+
# Sort the resources.
|
188
|
+
# The second and third arguments are what to sort by ("file", "mtime",
|
189
|
+
# or "size"), and whether to sort in order ("ascending") or reverse
|
190
|
+
# ("descending").
|
191
|
+
|
192
|
+
sorted_resources = Resource.sort(resources, $sort_item, $sort_direction)
|
193
|
+
|
194
|
+
##
|
195
|
+
# Set display variables and sort links based on sorting variables
|
196
|
+
|
197
|
+
file_link_dir = mtime_link_dir = sortby_link_dir = "ascending"
|
198
|
+
|
199
|
+
case $sort_item
|
200
|
+
when "file"
|
201
|
+
$sort_item_display = "alphabetically"
|
202
|
+
case $sort_direction
|
203
|
+
when "ascending"
|
204
|
+
$sort_direction_display = ""
|
205
|
+
file_link_dir = "descending"
|
206
|
+
when "descending"
|
207
|
+
$sort_direction_display = "reversed"
|
208
|
+
file_link_dir = "ascending"
|
209
|
+
end
|
210
|
+
when "mtime"
|
211
|
+
$sort_item_display = "by modification date"
|
212
|
+
case $sort_direction
|
213
|
+
when "ascending"
|
214
|
+
$sort_direction_display = "oldest to newest"
|
215
|
+
mtime_link_dir = "descending"
|
216
|
+
when "descending"
|
217
|
+
$sort_direction_display = "newest to oldest"
|
218
|
+
mtime_link_dir = "ascending"
|
219
|
+
end
|
220
|
+
when "size"
|
221
|
+
$sort_item_display = "by size"
|
222
|
+
case $sort_direction
|
223
|
+
when "ascending"
|
224
|
+
$sort_direction_display = "smallest to largest"
|
225
|
+
sortby_link_dir = "descending"
|
226
|
+
when "descending"
|
227
|
+
$sort_direction_display = "largest to smallest"
|
228
|
+
sortby_link_dir = "ascending"
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
$file_sort_link = "?sortby=file&direction=#{file_link_dir}"
|
233
|
+
$mtime_sort_link = "?sortby=mtime&direction=#{mtime_link_dir}"
|
234
|
+
$size_sort_link = "?sortby=size&direction=#{sortby_link_dir}"
|
235
|
+
|
236
|
+
##
|
237
|
+
# Finally, generate the html from the array of Resources.
|
238
|
+
|
239
|
+
sorted_resources.each do |resource|
|
240
|
+
$files_html << resource.wrap
|
255
241
|
end
|
256
242
|
end
|
257
243
|
|
258
244
|
##
|
259
245
|
# Generate and return the complete page from the erb template.
|
260
246
|
|
261
|
-
erb = ERB.new(
|
247
|
+
erb = ERB.new(LAYOUT)
|
262
248
|
erb.result
|
263
249
|
end
|
264
250
|
|
metadata
CHANGED
@@ -1,90 +1,119 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: directory_listing
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Richard Myers
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
15
|
name: filesize
|
16
|
-
|
17
|
-
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
21
|
version: 0.0.2
|
22
22
|
type: :runtime
|
23
|
-
version_requirements: *id001
|
24
|
-
- !ruby/object:Gem::Dependency
|
25
|
-
name: truncate
|
26
23
|
prerelease: false
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.0.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: truncate
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
31
37
|
version: 0.0.4
|
32
38
|
type: :runtime
|
33
|
-
version_requirements: *id002
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: bundler
|
36
39
|
prerelease: false
|
37
|
-
|
38
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.0.4
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
39
51
|
- - ~>
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version:
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
42
54
|
type: :development
|
43
|
-
version_requirements: *id003
|
44
|
-
- !ruby/object:Gem::Dependency
|
45
|
-
name: rake
|
46
55
|
prerelease: false
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
53
70
|
type: :development
|
54
|
-
|
55
|
-
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: A Sinatra extension for generating easy, CSS-styled, Apache-like directory
|
79
|
+
listings.
|
56
80
|
email: rick.myers@me.com
|
57
81
|
executables: []
|
58
|
-
|
59
82
|
extensions: []
|
60
|
-
|
61
83
|
extra_rdoc_files: []
|
62
|
-
|
63
|
-
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- LICENSE
|
87
|
+
- README.md
|
88
|
+
- Rakefile
|
89
|
+
- directory_listing.gemspec
|
64
90
|
- lib/sinatra/directory_listing.rb
|
91
|
+
- lib/sinatra/directory_listing/layout.rb
|
92
|
+
- lib/sinatra/directory_listing/resource.rb
|
93
|
+
- lib/sinatra/directory_listing/version.rb
|
65
94
|
homepage: https://rubygems.org/gems/directory_listing
|
66
|
-
licenses:
|
95
|
+
licenses:
|
67
96
|
- WTFPL
|
68
|
-
metadata: {}
|
69
|
-
|
70
97
|
post_install_message:
|
71
98
|
rdoc_options: []
|
72
|
-
|
73
|
-
require_paths:
|
99
|
+
require_paths:
|
74
100
|
- lib
|
75
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
81
113
|
requirements: []
|
82
|
-
|
83
114
|
rubyforge_project:
|
84
|
-
rubygems_version:
|
115
|
+
rubygems_version: 1.8.24
|
85
116
|
signing_key:
|
86
|
-
specification_version:
|
117
|
+
specification_version: 3
|
87
118
|
summary: Easy, CSS-styled, Apache-like directory listings for Sinatra.
|
88
119
|
test_files: []
|
89
|
-
|
90
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: fc6e8b90276b6880d8cc5eefca368b999056d6d7
|
4
|
-
data.tar.gz: 27e126e7c527ac9e756dc9b2d620b3614ebf9880
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: d2232198ba1bd9c8f62d2af86c23b2581e6bbaffc448fd9c8fd98805601cad2b536e3db4c82c7f7143d3c177e03a43d84cffa9cfecdcef4880b672a7f952a962
|
7
|
-
data.tar.gz: 62cbfe05a591976fe342694fd9664de8efa2f8bf16a8d872dd05fba2f42fe4fef060ead3234b690b0bf84529c1b122ae8669ff784a5ae8fbb0bf5f9bebf82012
|