directory_listing 0.2.2 → 0.3.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/.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
|