dropsite 0.2
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/LICENSE +21 -0
- data/README +25 -0
- data/Rakefile +33 -0
- data/bin/dropsite +38 -0
- data/dropsite.gemspec +28 -0
- data/lib/dropsite/dir_renderer.rb +56 -0
- data/lib/dropsite/plugins/simple_index/assets/css/reset.css +30 -0
- data/lib/dropsite/plugins/simple_index/assets/css/simple_index.css +98 -0
- data/lib/dropsite/plugins/simple_index/assets/images/icons/directory.png +0 -0
- data/lib/dropsite/plugins/simple_index/assets/images/icons/image.png +0 -0
- data/lib/dropsite/plugins/simple_index/assets/images/icons/pdf.png +0 -0
- data/lib/dropsite/plugins/simple_index/assets/images/icons/script.png +0 -0
- data/lib/dropsite/plugins/simple_index/assets/images/icons/text.png +0 -0
- data/lib/dropsite/plugins/simple_index/assets/images/icons/unknown.png +0 -0
- data/lib/dropsite/plugins/simple_index/assets/images/row-bg.png +0 -0
- data/lib/dropsite/plugins/simple_index/assets/simple_index.js +3 -0
- data/lib/dropsite/plugins/simple_index/simple_index.erb +37 -0
- data/lib/dropsite/plugins/simple_index/simple_index.rb +5 -0
- data/lib/dropsite/plugins.rb +5 -0
- data/lib/dropsite/render_helper.rb +97 -0
- data/lib/dropsite/site.rb +106 -0
- data/lib/dropsite/site_dir.rb +59 -0
- data/lib/dropsite/site_file.rb +41 -0
- data/lib/dropsite/site_item.rb +25 -0
- data/lib/dropsite.rb +30 -0
- data/test/fixtures/simple_public/file1.txt +1 -0
- data/test/fixtures/simple_public/file2.txt +1 -0
- data/test/fixtures/simple_public/pics/leaves.jpg +0 -0
- data/test/fixtures/simple_public/pics/people/beach.jpg +0 -0
- data/test/fixtures/simple_public/pics/people/concert.jpg +0 -0
- data/test/fixtures/simple_public/pics/sculpture.jpg +0 -0
- data/test/helper.rb +14 -0
- data/test/test_render_helper.rb +97 -0
- data/test/test_site.rb +41 -0
- data/test/test_site_dir.rb +20 -0
- data/test/test_site_file.rb +41 -0
- data/test/test_write_site.rb +102 -0
- metadata +107 -0
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2010 Aaron Royer
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
dropsite
|
2
|
+
gem install dropsite
|
3
|
+
|
4
|
+
Dropsite creates a site of interlinked file index pages in the Public directory
|
5
|
+
of your Dropbox. The site created is minimally invasive to your Public
|
6
|
+
directory by only creating one top-level HTML page and one folder, leaving your
|
7
|
+
directories unjunked.
|
8
|
+
|
9
|
+
BE WARNED: while this seems to work fine, it is presently considered
|
10
|
+
experimental.
|
11
|
+
|
12
|
+
To create the site:
|
13
|
+
$ dropsite
|
14
|
+
|
15
|
+
This deletes "index.html" and the directory "dropsite" in your Dropbox Public
|
16
|
+
directory if they exist, creates "index.html" as the top-level index, and puts
|
17
|
+
the rest of the index pages and assets in the "dropsite" directory.
|
18
|
+
|
19
|
+
To specify a different Dropbox directory:
|
20
|
+
$ dropsite --dropbox-home ~/Somewhere/Else
|
21
|
+
|
22
|
+
You can also use this if you just want to test this elsewhere before turning
|
23
|
+
it loose on your precious files.
|
24
|
+
|
25
|
+
MIT licensed - see LICENSE
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << 'lib'
|
7
|
+
t.pattern = 'test/**/test_*.rb'
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => [:test]
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'rcov/rcovtask'
|
14
|
+
Rcov::RcovTask.new do |t|
|
15
|
+
t.libs << 'test'
|
16
|
+
t.test_files = FileList['test/**/test_*.rb']
|
17
|
+
t.verbose = true
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::RDocTask.new do |rdoc|
|
23
|
+
rdoc.rdoc_dir = 'rdoc'
|
24
|
+
rdoc.title = 'dropsite'
|
25
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
26
|
+
rdoc.rdoc_files.include('README*')
|
27
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Build gem package"
|
31
|
+
task :package => 'dropsite.gemspec' do
|
32
|
+
sh "gem build dropsite.gemspec"
|
33
|
+
end
|
data/bin/dropsite
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
# TODO: take this out later
|
6
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
require 'dropsite'
|
8
|
+
include Dropsite
|
9
|
+
|
10
|
+
options = {
|
11
|
+
:quiet => false
|
12
|
+
}
|
13
|
+
|
14
|
+
OptionParser.new do |opts|
|
15
|
+
opts.on('-d', '--dropbox-home [PATH]', 'Specify Dropbox directory') {|path| options[:dropbox_home] = path }
|
16
|
+
opts.on('-q', '--quiet', 'Suppress site processing output') {|| options[:quiet] = true }
|
17
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
18
|
+
puts opts
|
19
|
+
exit
|
20
|
+
end
|
21
|
+
opts.on_tail('--version', 'Show version') do
|
22
|
+
puts "Dropsite version: #{Dropsite::VERSION}"
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
end.parse!
|
26
|
+
|
27
|
+
options[:dropbox_home] = Dropsite.find_dropbox_dir if not options[:dropbox_home]
|
28
|
+
|
29
|
+
if !options[:dropbox_home] || !File.exist?(options[:dropbox_home])
|
30
|
+
$stderr.puts 'Dropbox home directory cannot be found or does not exist'
|
31
|
+
$stderr.puts 'Set valid directory with --dropbox-home DIRECTORY'
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
|
35
|
+
options[:public_dir] = File.join(options[:dropbox_home], 'Public')
|
36
|
+
|
37
|
+
site = Dropsite::Site.new(options)
|
38
|
+
site.process
|
data/dropsite.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'dropsite'
|
3
|
+
s.version = '0.2'
|
4
|
+
s.platform = Gem::Platform::RUBY
|
5
|
+
|
6
|
+
s.description = "creates index pages in your Dropbox public directory"
|
7
|
+
s.summary = "Dropsite creates a site of interlinked file index pages in " +
|
8
|
+
"the Public directory of your Dropbox. The site created is minimally " +
|
9
|
+
"invasive to your Public directory by only creating one top-level " +
|
10
|
+
"HTML page and one folder, leaving your directories unjunked." +
|
11
|
+
"\nBE WARNED: while I _think_ this probably works fine, it is " +
|
12
|
+
"presently considered experimental."
|
13
|
+
|
14
|
+
s.authors = ["Aaron Royer"]
|
15
|
+
s.email = "aaronroyer@gmail.com"
|
16
|
+
|
17
|
+
s.files = Dir['{bin/*,lib/**/*,test/**/*}'] +
|
18
|
+
%w(README LICENSE dropsite.gemspec Rakefile)
|
19
|
+
|
20
|
+
s.executables << 'dropsite'
|
21
|
+
|
22
|
+
s.test_files = s.files.select {|path| path =~ /^test\/test_.*\.rb/}
|
23
|
+
|
24
|
+
s.has_rdoc = true
|
25
|
+
s.homepage = "https://rubygems.org/gems/dropsite"
|
26
|
+
s.rdoc_options = ["--line-numbers", "--inline-source"]
|
27
|
+
s.require_paths = %w[lib]
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Dropsite
|
4
|
+
class DirRenderer
|
5
|
+
TEMPLATE_EXTENSIONS = ['.erb']
|
6
|
+
|
7
|
+
@@renderers = []
|
8
|
+
|
9
|
+
def self.inherited(subclass)
|
10
|
+
renderer = subclass.new
|
11
|
+
|
12
|
+
plugin_dir = File.dirname(caller[0].split(':')[0])
|
13
|
+
template_file = Dir.entries(plugin_dir).find {|e| TEMPLATE_EXTENSIONS.include? File.extname(e)}
|
14
|
+
renderer.template_path = template_file ? File.join(plugin_dir, template_file) : nil
|
15
|
+
renderer.assets_dir = File.join(plugin_dir, 'assets')
|
16
|
+
@@renderers << renderer
|
17
|
+
end
|
18
|
+
|
19
|
+
def DirRenderer.renderers
|
20
|
+
@@renderers
|
21
|
+
end
|
22
|
+
|
23
|
+
# Find the first renderer that can render the given SiteDir. Non-default (user) plugins
|
24
|
+
# are searched first.
|
25
|
+
def DirRenderer.find_renderer(site_dir)
|
26
|
+
@@renderers.partition {|r| !r.is_default? }.flatten.find {|r| r.can_render?(site_dir)}
|
27
|
+
end
|
28
|
+
|
29
|
+
def DirRenderer.find_renderer_and_render(site_dir)
|
30
|
+
DirRenderer.find_renderer(site_dir).render(site_dir)
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_accessor :template_path, :assets_dir
|
34
|
+
|
35
|
+
# Overridden in subclass if you don't want to just find and use a template
|
36
|
+
def render(site_dir)
|
37
|
+
site_dir.rendered_by = self.class
|
38
|
+
|
39
|
+
if File.extname(template_path) == '.erb'
|
40
|
+
@template = @template || ERB.new(IO.read(template_path))
|
41
|
+
@template.result(site_dir.get_binding)
|
42
|
+
else
|
43
|
+
raise "Don't know how to render: #{template_path}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Overriden in subclass or this won't do jack
|
48
|
+
def can_render?(site_dir)
|
49
|
+
is_default?
|
50
|
+
end
|
51
|
+
|
52
|
+
def is_default?
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {
|
2
|
+
margin:0;
|
3
|
+
padding:0;
|
4
|
+
}
|
5
|
+
table {
|
6
|
+
border-collapse:collapse;
|
7
|
+
border-spacing:0;
|
8
|
+
}
|
9
|
+
fieldset,img {
|
10
|
+
border:0;
|
11
|
+
}
|
12
|
+
address,caption,cite,code,dfn,em,strong,th,var {
|
13
|
+
font-style:normal;
|
14
|
+
font-weight:normal;
|
15
|
+
}
|
16
|
+
ol,ul {
|
17
|
+
list-style:none;
|
18
|
+
}
|
19
|
+
caption,th {
|
20
|
+
text-align:left;
|
21
|
+
}
|
22
|
+
h1,h2,h3,h4,h5,h6 {
|
23
|
+
font-size:100%;
|
24
|
+
font-weight:normal;
|
25
|
+
}
|
26
|
+
q:before,q:after {
|
27
|
+
content:'';
|
28
|
+
}
|
29
|
+
abbr,acronym { border:0;
|
30
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
body {
|
2
|
+
background-color: white;
|
3
|
+
color: #484848;
|
4
|
+
font: 13.34px Helvetica, Arial, freesans, clean, sans-serif;
|
5
|
+
font-size: 90%;
|
6
|
+
text-align: center;
|
7
|
+
}
|
8
|
+
|
9
|
+
#content {
|
10
|
+
width: 920px;
|
11
|
+
margin-left: auto;
|
12
|
+
margin-right: auto;
|
13
|
+
text-align: left;
|
14
|
+
}
|
15
|
+
|
16
|
+
#breadcrumbs {
|
17
|
+
margin-top: 20px;
|
18
|
+
font-size: 140%;
|
19
|
+
}
|
20
|
+
|
21
|
+
#breadcrumbs .sep {
|
22
|
+
margin-left: 5px;
|
23
|
+
margin-right: 10px;
|
24
|
+
}
|
25
|
+
|
26
|
+
#breadcrumbs .root-link, #breadcrumbs .parent-dir-link {
|
27
|
+
text-decoration: none;
|
28
|
+
}
|
29
|
+
|
30
|
+
#breadcrumbs .root-link:hover, .parent-dir-link:hover {
|
31
|
+
text-decoration: underline;
|
32
|
+
}
|
33
|
+
|
34
|
+
#breadcrumbs .root-link {
|
35
|
+
color: #4183C4;
|
36
|
+
font-weight: bold;
|
37
|
+
}
|
38
|
+
|
39
|
+
#breadcrumbs .parent-dir-link {
|
40
|
+
color: #4183C4;
|
41
|
+
}
|
42
|
+
|
43
|
+
#breadcrumbs .current-dir {
|
44
|
+
color: #000000;
|
45
|
+
}
|
46
|
+
|
47
|
+
#file-list {
|
48
|
+
margin-top: 10px;
|
49
|
+
width: 100%;
|
50
|
+
}
|
51
|
+
|
52
|
+
#file-list .header {
|
53
|
+
background-color: #eaeaea;
|
54
|
+
border: 1px solid #e1e1e1;
|
55
|
+
color: #999999;
|
56
|
+
height: 28px;
|
57
|
+
}
|
58
|
+
|
59
|
+
.entry {
|
60
|
+
height: 28px;
|
61
|
+
border: 1px solid #e1e1e1;
|
62
|
+
border-top: none;
|
63
|
+
background-image: url(../images/row-bg.png);
|
64
|
+
font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
65
|
+
}
|
66
|
+
|
67
|
+
.entry td {
|
68
|
+
vertical-align: middle;
|
69
|
+
}
|
70
|
+
|
71
|
+
.entry td a {
|
72
|
+
color: #4183C4;
|
73
|
+
text-decoration: none;
|
74
|
+
}
|
75
|
+
|
76
|
+
.entry td a:hover {
|
77
|
+
text-decoration: underline;
|
78
|
+
}
|
79
|
+
|
80
|
+
.entry .icon {
|
81
|
+
width: 28px;
|
82
|
+
padding-left: 12px;
|
83
|
+
padding-top: 4px;
|
84
|
+
}
|
85
|
+
|
86
|
+
.entry .link {
|
87
|
+
min-width: 300px;
|
88
|
+
}
|
89
|
+
|
90
|
+
.entry .type {
|
91
|
+
padding-right: 10px;
|
92
|
+
min-width: 120px;
|
93
|
+
}
|
94
|
+
|
95
|
+
.entry .size {
|
96
|
+
padding-right: 10px;
|
97
|
+
min-width: 70px;
|
98
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
2
|
+
"http://www.w3.org/TR/html4/strict.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
6
|
+
<title>My Dropbox Files<%= " - #{name}" if !root? %></title>
|
7
|
+
<%= stylesheet_link_tag 'reset' %>
|
8
|
+
<%= stylesheet_link_tag 'simple_index' %>
|
9
|
+
<%= javascript_include_tag 'simple_index' %>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div id="content">
|
13
|
+
<div id="breadcrumbs">
|
14
|
+
<a class="root-link" href="<%= back_link('root') %>">my files</a>
|
15
|
+
<% each_parent_directory_link_tag(false, {:class => 'parent-dir-link'}) do |tag| %>
|
16
|
+
<span class="sep">/</span><%= tag %>
|
17
|
+
<% end %>
|
18
|
+
<% if !root? %>
|
19
|
+
<span class="sep">/</span><span class="current-dir"><%= name %></span>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
|
+
<table id="file-list">
|
23
|
+
<tr class="header">
|
24
|
+
<th> </th><th>name</th><th>type</th><th>size</th>
|
25
|
+
</tr>
|
26
|
+
<% @entries.sort.each do |entry| %>
|
27
|
+
<tr class="entry">
|
28
|
+
<td class="icon"><%= image_tag "icons/#{entry.file_type}.png" %></td>
|
29
|
+
<td class="link"><a href="<%= entry.link %>"><%= entry.name %></a></td>
|
30
|
+
<td class="type"><%= entry.file_type %></td>
|
31
|
+
<td class="size"><%= entry.size %></td>
|
32
|
+
</tr>
|
33
|
+
<% end %>
|
34
|
+
</table>
|
35
|
+
</div>
|
36
|
+
</body>
|
37
|
+
</html>
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Dropsite
|
2
|
+
|
3
|
+
# Helper methods, accessible in templates, to be included in renderable items
|
4
|
+
module RenderHelper
|
5
|
+
attr_accessor :rendered_by
|
6
|
+
|
7
|
+
def link
|
8
|
+
# TODO: URL escape links
|
9
|
+
if top_level? && (!is_a? SiteDir)
|
10
|
+
name
|
11
|
+
else
|
12
|
+
if is_a? SiteDir # TODO: do a dynamic renderable test?
|
13
|
+
top_level? ? "dropsite/#{@path}.html" : "#{@path}.html".sub(/^\//, '')
|
14
|
+
else
|
15
|
+
# Builds a link back up to the file in Public root since the pages
|
16
|
+
# are built in a parallel directory structure
|
17
|
+
dirs_up = @path.split(File::SEPARATOR).size - 1
|
18
|
+
(['..'] * dirs_up).join('/') + "/#{@path}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def stylesheet_link_tag(stylesheet_name)
|
24
|
+
stylesheet_name = "#{stylesheet_name}.css" if not stylesheet_name =~ /\.css$/
|
25
|
+
%{<link rel="stylesheet" href="#{assets_link_base}css/#{stylesheet_name}" type="text/css" media="screen">}
|
26
|
+
end
|
27
|
+
|
28
|
+
def javascript_include_tag(javascript_file_name)
|
29
|
+
javascript_file_name = "#{javascript_file_name}.js" if not javascript_file_name =~ /\.js$/
|
30
|
+
%{<script type="text/javascript" src="#{assets_link_base}js/#{javascript_file_name}"></script>}
|
31
|
+
end
|
32
|
+
|
33
|
+
def image_tag(image_file_name)
|
34
|
+
%{<img src="#{assets_link_base}images/#{image_file_name}" />}
|
35
|
+
end
|
36
|
+
|
37
|
+
def parent_directory_link_tag(levels_up=1, options={})
|
38
|
+
%{<a href="#{back_link(levels_up)}"#{tag_attributes(options)}>#{parent_dir_name(levels_up)}</a>}
|
39
|
+
end
|
40
|
+
|
41
|
+
def each_parent_directory_link_tag(*args)
|
42
|
+
include_root = true
|
43
|
+
include_root = args[0] if args.size > 0 && (!args[0].is_a? Hash)
|
44
|
+
options = args.find {|arg| arg.is_a? Hash}
|
45
|
+
options = {} if !options
|
46
|
+
|
47
|
+
levels_up = path.split('/').size
|
48
|
+
levels_up = levels_up - 1 if !include_root
|
49
|
+
levels_up.downto(1).each do |level_up|
|
50
|
+
yield parent_directory_link_tag(level_up, options)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def assets_link_base
|
55
|
+
if root?
|
56
|
+
"dropsite/dropsite-assets/#{Dropsite.underscorize(rendered_by)}/"
|
57
|
+
else
|
58
|
+
# Work our way BACK up the path - crazy, right? Gotta do it though.
|
59
|
+
dirs_up = path.split(File::SEPARATOR).size - 1
|
60
|
+
(['..'] * dirs_up).join('/') + "#{'/' if dirs_up > 0}dropsite-assets/#{Dropsite.underscorize(rendered_by)}/"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get a link to a parent page
|
65
|
+
def back_link(levels_up=1)
|
66
|
+
# TODO: factor this out a bit between parent_dir_name
|
67
|
+
if levels_up.is_a?(Integer) && levels_up > 0 && levels_up < path.split('/').size
|
68
|
+
dir_name = path.split('/')[(levels_up + 1) * -1]
|
69
|
+
dir_name = 'index' if dir_name.empty?
|
70
|
+
(['..'] * (levels_up)).join('/') + "/#{dir_name}.html"
|
71
|
+
else
|
72
|
+
# Give the root index if we're confused
|
73
|
+
root? ? '' : (['..'] * (path.split('/').size)).join('/') + '/index.html'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def parent_dir_name(levels_up=1)
|
78
|
+
if levels_up.is_a?(Integer) && levels_up > 0 && levels_up < path.split('/').size
|
79
|
+
dir_name = path.split('/')[(levels_up + 1) * -1]
|
80
|
+
dir_name.empty? ? 'index' : dir_name
|
81
|
+
else
|
82
|
+
# TODO: make this configurable
|
83
|
+
'my files'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_binding
|
88
|
+
binding
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
def tag_attributes(options)
|
94
|
+
options.empty? ? '' : ' ' + options.keys.map {|k| %{#{k.to_s}="#{options[k].to_s}"} }.join
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Dropsite
|
4
|
+
VERSION = '0.2'
|
5
|
+
|
6
|
+
# Main site builder class. Some inspiration here from Jekyll (github.com/mojombo/jekyll).
|
7
|
+
class Site
|
8
|
+
attr_reader :site_tree, :public_dir
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
if config.is_a? String
|
12
|
+
@public_dir = config
|
13
|
+
@excludes = []
|
14
|
+
@quiet = false
|
15
|
+
else
|
16
|
+
@config = config.clone
|
17
|
+
@public_dir = config[:public_dir]
|
18
|
+
@excludes = config[:excludes] || []
|
19
|
+
@quiet = config[:quiet] || false
|
20
|
+
end
|
21
|
+
|
22
|
+
@site_tree = nil
|
23
|
+
@site_files_dir = File.join(@public_dir, 'dropsite')
|
24
|
+
end
|
25
|
+
|
26
|
+
def process
|
27
|
+
clean
|
28
|
+
read
|
29
|
+
render
|
30
|
+
write
|
31
|
+
end
|
32
|
+
|
33
|
+
# Cleans up files previously generated by Dropsite (or at least ones)
|
34
|
+
# that look like they are. By default this will be an index.html
|
35
|
+
# file and dropsite directory in the Public directory root.
|
36
|
+
def clean
|
37
|
+
if File.exist?(@site_files_dir)
|
38
|
+
notice "Deleting existing site files dir at #{@site_files_dir}"
|
39
|
+
FileUtils.rm_rf(@site_files_dir)
|
40
|
+
end
|
41
|
+
|
42
|
+
index_file = File.join(@public_dir, 'index.html')
|
43
|
+
if File.exist?(index_file)
|
44
|
+
notice "Deleting existing top-level index at #{index_file}"
|
45
|
+
File.delete(index_file)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def read
|
50
|
+
@site_tree = read_directory
|
51
|
+
end
|
52
|
+
|
53
|
+
def render
|
54
|
+
@site_tree.render
|
55
|
+
end
|
56
|
+
|
57
|
+
def write
|
58
|
+
notice "Creating site files dir at #{@site_files_dir}"
|
59
|
+
Dir.mkdir(@site_files_dir)
|
60
|
+
@site_tree.write
|
61
|
+
|
62
|
+
site_assets_dir = File.join(@site_files_dir, 'dropsite-assets')
|
63
|
+
Dir.mkdir(site_assets_dir)
|
64
|
+
DirRenderer.renderers.each do |r|
|
65
|
+
if File.exist? r.assets_dir
|
66
|
+
FileUtils.cp_r(r.assets_dir, File.join(site_assets_dir, Dropsite.underscorize(r.class.to_s)))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def notice(message)
|
72
|
+
return if @quiet
|
73
|
+
warn "#{File.basename($0)}: #{message}"
|
74
|
+
end
|
75
|
+
|
76
|
+
protected
|
77
|
+
|
78
|
+
def read_directory(dir='')
|
79
|
+
base = File.join(@public_dir, dir)
|
80
|
+
entries = filter_entries(Dir.entries(base))
|
81
|
+
|
82
|
+
dir_entries = []
|
83
|
+
|
84
|
+
entries.each do |f|
|
85
|
+
f_abs = File.join(base, f)
|
86
|
+
f_rel = File.join(dir, f).sub(/^\//, '')
|
87
|
+
if File.directory?(f_abs)
|
88
|
+
dir_entries << read_directory(f_rel)
|
89
|
+
elsif !File.symlink?(f_abs)
|
90
|
+
# Ignore a top level Icon file, used for a custom directory icon on OS X
|
91
|
+
# TODO: find out how to do this specifically for the Icon file... there is a
|
92
|
+
# weird character at the end of the folder icon file name
|
93
|
+
next if RUBY_PLATFORM =~ /darwin/ && f_rel =~ /^Icon/ && f_rel.size == 5 && dir == ''
|
94
|
+
dir_entries << SiteFile.new(f_rel, f_abs, self)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
SiteDir.new(dir, dir_entries, self)
|
98
|
+
end
|
99
|
+
|
100
|
+
def filter_entries(entries)
|
101
|
+
entries.reject do |e|
|
102
|
+
['.', '_', '#'].include?(e[0..0]) || e[-1..-1] == '~' || @excludes.include?(e)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Dropsite
|
2
|
+
class SiteDir < SiteItem
|
3
|
+
attr_accessor :entries
|
4
|
+
|
5
|
+
def initialize(path, entries, site)
|
6
|
+
@path = path == '/' ? '' : path
|
7
|
+
@entries = entries
|
8
|
+
@site = site
|
9
|
+
@content = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def render
|
13
|
+
@content = Dropsite::DirRenderer.find_renderer_and_render(self)
|
14
|
+
dirs.each {|dir| dir.render}
|
15
|
+
end
|
16
|
+
|
17
|
+
def write
|
18
|
+
if root?
|
19
|
+
# The root site directory was created in Site
|
20
|
+
index_file = File.join(@site.public_dir, 'index.html')
|
21
|
+
notice "Writing top level index file at #{index_file}"
|
22
|
+
File.open(index_file, 'w') {|f| f.puts @content}
|
23
|
+
else
|
24
|
+
# Sub-directories all need to be created here
|
25
|
+
pieces = @path.sub(/^\//, '').split('/')
|
26
|
+
dir_name = File.join(@site.public_dir, 'dropsite', *pieces)
|
27
|
+
index_file = dir_name + '.html'
|
28
|
+
notice "Writing index file at #{index_file}"
|
29
|
+
File.open(index_file, 'w') {|f| f.puts @content}
|
30
|
+
Dir.mkdir(dir_name)
|
31
|
+
end
|
32
|
+
dirs.sort.each{|dir| dir.write}
|
33
|
+
end
|
34
|
+
|
35
|
+
def files
|
36
|
+
@entries.find_all {|e| e.is_a? SiteFile}
|
37
|
+
end
|
38
|
+
|
39
|
+
def dirs
|
40
|
+
@entries.find_all {|e| e.is_a? SiteDir}
|
41
|
+
end
|
42
|
+
|
43
|
+
def root?
|
44
|
+
@path == ''
|
45
|
+
end
|
46
|
+
|
47
|
+
def file_type
|
48
|
+
'directory'
|
49
|
+
end
|
50
|
+
|
51
|
+
def size
|
52
|
+
''
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
"SiteDir(#{is_root? ? 'root' : @path})"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Dropsite
|
2
|
+
class SiteFile < SiteItem
|
3
|
+
EXTENSIONS = {
|
4
|
+
'image' => %w[jpg jpeg gif png],
|
5
|
+
'text' => %w[txt],
|
6
|
+
'pdf' => %w[pdf]
|
7
|
+
}
|
8
|
+
|
9
|
+
attr_accessor :size_in_bytes
|
10
|
+
|
11
|
+
def initialize(rel_path, abs_path=nil, site=nil)
|
12
|
+
@path = rel_path
|
13
|
+
@size_in_bytes = File.size(abs_path) if abs_path
|
14
|
+
@site = site
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_type
|
18
|
+
if File.extname(name).empty?
|
19
|
+
'unknown'
|
20
|
+
else
|
21
|
+
ext = File.extname(name).sub(/^\./, '')
|
22
|
+
EXTENSIONS.each {|k, v| return k if v.include? ext}
|
23
|
+
return 'unknown'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Human readable file size
|
28
|
+
def size
|
29
|
+
return '' if !@size_in_bytes
|
30
|
+
return '0 B' if @size_in_bytes == 0
|
31
|
+
units = %w{B KB MB GB TB}
|
32
|
+
e = (Math.log(@size_in_bytes)/Math.log(1024)).floor
|
33
|
+
s = "%.1f" % (@size_in_bytes.to_f / 1024 ** e)
|
34
|
+
s.sub(/\.?0*$/, " #{units[e]}")
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
"SiteFile(#{@path})"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Dropsite
|
2
|
+
class SiteItem
|
3
|
+
include Enumerable, RenderHelper
|
4
|
+
|
5
|
+
attr_accessor :path
|
6
|
+
|
7
|
+
def name
|
8
|
+
File.basename @path
|
9
|
+
end
|
10
|
+
|
11
|
+
def top_level?
|
12
|
+
@path.sub(/^\//, '') == name
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=>(other)
|
16
|
+
name <=> other.name
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def notice(message)
|
22
|
+
@site.notice(message) if @site
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/dropsite.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
module Dropsite
|
3
|
+
|
4
|
+
# Attempts to find the Dropbox directory (not the Public directory, the Dropbox base
|
5
|
+
# directory) on this box. Returns nil if an existing directory could not be found.
|
6
|
+
def find_dropbox_dir
|
7
|
+
return ENV['DROPBOX_HOME'] if ENV['DROPBOX_HOME']
|
8
|
+
|
9
|
+
path = case RUBY_PLATFORM
|
10
|
+
when /darwin/, /linux/, /freebsd/
|
11
|
+
File.join(ENV['HOME'], 'Dropbox')
|
12
|
+
when /win32/, /mingw/
|
13
|
+
File.join(ENV['USERPROFILE'], 'My Documents', 'My Dropbox')
|
14
|
+
end
|
15
|
+
|
16
|
+
File.exist?(path) ? path : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
# Convert a camel-cased string into a lowercase, underscore separated string
|
20
|
+
def underscorize(camel_cased_word)
|
21
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
22
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
23
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
24
|
+
tr("-", "_").downcase
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
%w[dir_renderer render_helper plugins site site_item site_dir site_file].each do |lib|
|
29
|
+
require File.join('dropsite', lib)
|
30
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
here is some content
|
@@ -0,0 +1 @@
|
|
1
|
+
here is some content
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/test/helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'redgreen' unless ENV['TM_MODE']
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
|
9
|
+
FILE_DIR = File.dirname(__FILE__)
|
10
|
+
|
11
|
+
require File.join(FILE_DIR, *%w[.. lib dropsite])
|
12
|
+
include Dropsite
|
13
|
+
|
14
|
+
FIXTURES_DIR = File.join(FILE_DIR, 'fixtures')
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
# Tests for RenderHelper mixin using SiteItem, which mixes it in
|
5
|
+
class TestRenderHelper < Test::Unit::TestCase
|
6
|
+
def test_back_link
|
7
|
+
assert_equal '../index.html', SiteDir.new('pics', [], '/tmp').back_link(1)
|
8
|
+
assert_equal '../index.html', SiteDir.new('pics', [], '/tmp').back_link
|
9
|
+
assert_equal '../pics.html', SiteDir.new('pics/people', [], '/tmp').back_link(1)
|
10
|
+
assert_equal '../../index.html', SiteDir.new('pics/people', [], '/tmp').back_link(2)
|
11
|
+
assert_equal '../people.html', SiteDir.new('pics/people/friends', [], '/tmp').back_link(1)
|
12
|
+
assert_equal '../../pics.html', SiteDir.new('pics/people/friends', [], '/tmp').back_link(2)
|
13
|
+
assert_equal '../../../index.html', SiteDir.new('pics/people/friends', [], '/tmp').back_link(3)
|
14
|
+
|
15
|
+
# Test too many levels up and non-Integer arg
|
16
|
+
assert_equal '../index.html', SiteDir.new('pics', [], '/tmp').back_link(2)
|
17
|
+
assert_equal '../index.html', SiteDir.new('pics', [], '/tmp').back_link(3)
|
18
|
+
assert_equal '../index.html', SiteDir.new('pics', [], '/tmp').back_link(nil)
|
19
|
+
assert_equal '', SiteDir.new('', [], '/tmp').back_link(1)
|
20
|
+
assert_equal '', SiteDir.new('', [], '/tmp').back_link(nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_parent_directory_link_tag
|
24
|
+
sd = SiteDir.new('pics/people/friends', [], '/tmp')
|
25
|
+
|
26
|
+
basic_link_doc = Nokogiri::HTML(sd.parent_directory_link_tag(1))
|
27
|
+
links = basic_link_doc.css('a')
|
28
|
+
assert_equal 1, links.size
|
29
|
+
assert_equal '../people.html', links[0].attribute('href').value
|
30
|
+
assert_equal 'people', links[0].content
|
31
|
+
|
32
|
+
basic_link_doc = Nokogiri::HTML(sd.parent_directory_link_tag(2))
|
33
|
+
links = basic_link_doc.css('a')
|
34
|
+
assert_equal 1, links.size
|
35
|
+
assert_equal '../../pics.html', links[0].attribute('href').value
|
36
|
+
assert_equal 'pics', links[0].content
|
37
|
+
|
38
|
+
basic_link_doc = Nokogiri::HTML(sd.parent_directory_link_tag(3))
|
39
|
+
links = basic_link_doc.css('a')
|
40
|
+
assert_equal 1, links.size
|
41
|
+
assert_equal '../../../index.html', links[0].attribute('href').value
|
42
|
+
assert_equal 'my files', links[0].content
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_parent_directory_link_tag_with_additional_attributes
|
46
|
+
sd = SiteDir.new('pics/people/friends', [], '/tmp')
|
47
|
+
id = 'the-id'
|
48
|
+
css_class = 'the-css-class'
|
49
|
+
|
50
|
+
link_doc = Nokogiri::HTML(sd.parent_directory_link_tag(1, :class => css_class))
|
51
|
+
links = link_doc.css('a')
|
52
|
+
assert_equal 1, links.size
|
53
|
+
link = links[0]
|
54
|
+
assert_equal '../people.html', link.attribute('href').value
|
55
|
+
assert_equal 'people', link.content
|
56
|
+
assert_equal css_class, link.attribute('class').value
|
57
|
+
|
58
|
+
link_doc = Nokogiri::HTML(sd.parent_directory_link_tag(1, :id => id, :class => css_class))
|
59
|
+
links = link_doc.css('a')
|
60
|
+
assert_equal 1, links.size
|
61
|
+
link = links[0]
|
62
|
+
assert_equal '../people.html', link.attribute('href').value
|
63
|
+
assert_equal 'people', link.content
|
64
|
+
assert_equal id, link.attribute('id').value
|
65
|
+
assert_equal css_class, link.attribute('class').value
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_each_parent_directory_link_tag_with_root
|
69
|
+
links = ''
|
70
|
+
sd = SiteDir.new('pics/people/friends', [], '/tmp')
|
71
|
+
sd.each_parent_directory_link_tag {|link| links << link}
|
72
|
+
links_doc = Nokogiri::HTML(links)
|
73
|
+
links = links_doc.css('a')
|
74
|
+
assert_equal 3, links.size
|
75
|
+
|
76
|
+
root_link = links_doc.css('a').find {|a| a.content == 'my files'}
|
77
|
+
assert_equal '../../../index.html', root_link.attribute('href').value
|
78
|
+
pics_link = links_doc.css('a').find {|a| a.content == 'pics'}
|
79
|
+
assert_equal '../../pics.html', pics_link.attribute('href').value
|
80
|
+
people_link = links_doc.css('a').find {|a| a.content == 'people'}
|
81
|
+
assert_equal '../people.html', people_link.attribute('href').value
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_each_parent_directory_link_tag_without_root
|
85
|
+
links = ''
|
86
|
+
sd = SiteDir.new('pics/people/friends', [], '/tmp')
|
87
|
+
sd.each_parent_directory_link_tag(false) {|link| links << link}
|
88
|
+
links_doc = Nokogiri::HTML(links)
|
89
|
+
links = links_doc.css('a')
|
90
|
+
assert_equal 2, links.size
|
91
|
+
|
92
|
+
pics_link = links_doc.css('a').find {|a| a.content == 'pics'}
|
93
|
+
assert_equal '../../pics.html', pics_link.attribute('href').value
|
94
|
+
people_link = links_doc.css('a').find {|a| a.content == 'people'}
|
95
|
+
assert_equal '../people.html', people_link.attribute('href').value
|
96
|
+
end
|
97
|
+
end
|
data/test/test_site.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
class TestSite < Test::Unit::TestCase
|
4
|
+
def test_create_site_tree_from_simple_public_dir
|
5
|
+
site = Site.new(File.join(FIXTURES_DIR, 'simple_public'))
|
6
|
+
root = site.read
|
7
|
+
|
8
|
+
assert root.is_a? SiteDir
|
9
|
+
assert_equal '', root.path
|
10
|
+
assert_equal 2, root.files.size
|
11
|
+
assert root.files.find {|f| f.name == 'file1.txt'}
|
12
|
+
assert root.files.find {|f| f.name == 'file2.txt'}
|
13
|
+
assert_equal 1, root.dirs.size
|
14
|
+
|
15
|
+
pics_dir = root.dirs[0]
|
16
|
+
assert_equal 'pics', pics_dir.path
|
17
|
+
assert_equal 2, pics_dir.files.size
|
18
|
+
|
19
|
+
assert pics_dir.files.find {|f| f.name == 'leaves.jpg'}
|
20
|
+
assert pics_dir.files.find {|f| f.name == 'sculpture.jpg'}
|
21
|
+
assert_equal 1, pics_dir.dirs.size
|
22
|
+
|
23
|
+
people_dir = pics_dir.dirs[0]
|
24
|
+
assert_equal 2, people_dir.files.size
|
25
|
+
assert people_dir.files.find {|f| f.name == 'concert.jpg'}
|
26
|
+
assert people_dir.files.find {|f| f.name == 'beach.jpg'}
|
27
|
+
assert people_dir.dirs.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_create_site_tree_from_simple_public_dir_with_exclusions
|
31
|
+
site = Site.new(
|
32
|
+
:public_dir => File.join(FIXTURES_DIR, 'simple_public'),
|
33
|
+
:excludes => ['pics', 'file1.txt']
|
34
|
+
)
|
35
|
+
root = site.read
|
36
|
+
|
37
|
+
assert_equal 1, root.files.size
|
38
|
+
assert root.files.find {|f| f.name == 'file2.txt'}
|
39
|
+
assert root.dirs.empty?
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
class TestSiteDir < Test::Unit::TestCase
|
4
|
+
def test_name
|
5
|
+
assert_equal 'pic1.jpg', SiteDir.new('pic1.jpg', [], '/tmp').name
|
6
|
+
assert_equal 'pic1.jpg', SiteDir.new('/pics/pic1.jpg', [], '/tmp').name
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_root_name
|
10
|
+
assert_equal '', SiteDir.new('/', [], '/tmp').name
|
11
|
+
assert_equal '', SiteDir.new('', [], '/tmp').name
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_is_root
|
15
|
+
assert SiteDir.new('', [], '/tmp').root?
|
16
|
+
assert !SiteDir.new('/file.txt', [], '/tmp').root?
|
17
|
+
assert !SiteDir.new('/dir', [], '/tmp').root?
|
18
|
+
assert !SiteDir.new('/dir/file.txt', [], '/tmp').root?
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
|
3
|
+
class TestSiteFile < Test::Unit::TestCase
|
4
|
+
def test_name
|
5
|
+
assert_equal 'pic1.jpg', SiteFile.new('pic1.jpg').name
|
6
|
+
assert_equal 'pic1.jpg', SiteFile.new('/pics/pic1.jpg').name
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_type
|
10
|
+
assert_equal 'image', SiteFile.new('/pics/pic1.jpg').file_type
|
11
|
+
assert_equal 'image', SiteFile.new('/pics/pic1.gif').file_type
|
12
|
+
assert_equal 'text', SiteFile.new('/pics/pic1.txt').file_type
|
13
|
+
assert_equal 'unknown', SiteFile.new('/pics/plainoldfile').file_type
|
14
|
+
assert_equal 'unknown', SiteFile.new('/pics/file.asdf').file_type
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_top_level
|
18
|
+
assert SiteFile.new('/pic1.jpg').top_level?
|
19
|
+
assert !SiteFile.new('/pics/pic1.jpg').top_level?
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_size
|
23
|
+
sf = SiteFile.new('/pic1.jpg')
|
24
|
+
sf.size_in_bytes = 100
|
25
|
+
assert_equal '100 B', sf.size
|
26
|
+
sf.size_in_bytes = 1024
|
27
|
+
assert_equal '1 KB', sf.size
|
28
|
+
sf.size_in_bytes = 1536
|
29
|
+
assert_equal '1.5 KB', sf.size
|
30
|
+
sf.size_in_bytes = 1792
|
31
|
+
assert_equal '1.8 KB', sf.size # rounded
|
32
|
+
sf.size_in_bytes = 1048576
|
33
|
+
assert_equal '1 MB', sf.size
|
34
|
+
sf.size_in_bytes = 3879731
|
35
|
+
assert_equal '3.7 MB', sf.size
|
36
|
+
sf.size_in_bytes = 1073741824
|
37
|
+
assert_equal '1 GB', sf.size
|
38
|
+
sf.size_in_bytes = 1099511627776
|
39
|
+
assert_equal '1 TB', sf.size
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'helper')
|
2
|
+
require 'fileutils'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
class TestWriteSite < Test::Unit::TestCase
|
6
|
+
TMP_DIR = File.join(FIXTURES_DIR, 'tmp')
|
7
|
+
|
8
|
+
def setup
|
9
|
+
clean_tmp_dir
|
10
|
+
end
|
11
|
+
|
12
|
+
def teardown
|
13
|
+
clean_tmp_dir
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_simple_process
|
17
|
+
FileUtils.cp_r(File.join(FIXTURES_DIR, 'simple_public'), File.join(TMP_DIR, 'simple_public'))
|
18
|
+
site = Site.new(:public_dir => File.join(TMP_DIR, 'simple_public'), :quiet => true)
|
19
|
+
site.process
|
20
|
+
|
21
|
+
# Check that all the index pages are there
|
22
|
+
|
23
|
+
index_file = File.join(site.public_dir, 'index.html')
|
24
|
+
assert File.exist?(index_file)
|
25
|
+
index_doc = Nokogiri::HTML(IO.read(index_file))
|
26
|
+
assert_equal 3, index_doc.css('.entry').size
|
27
|
+
|
28
|
+
assert_equal 'dropsite/pics.html', index_doc.css('a').find {|a| a.content == 'pics'}.attribute('href').value
|
29
|
+
|
30
|
+
site_dir = File.join(site.public_dir, 'dropsite')
|
31
|
+
assert File.exist?(site_dir)
|
32
|
+
assert File.directory?(site_dir)
|
33
|
+
|
34
|
+
pics_file = File.join(site_dir, 'pics.html')
|
35
|
+
assert File.exist?(pics_file)
|
36
|
+
pics_doc = Nokogiri::HTML(IO.read(pics_file))
|
37
|
+
assert_equal 3, pics_doc.css('.entry').size
|
38
|
+
|
39
|
+
# Make sure the the links are correct
|
40
|
+
|
41
|
+
['leaves.jpg', 'sculpture.jpg'].each do |pic|
|
42
|
+
assert_equal "../pics/#{pic}", pics_doc.css('a').find {|a| a.content == pic}.attribute('href').value
|
43
|
+
end
|
44
|
+
|
45
|
+
assert_equal 'pics/people.html', pics_doc.css('a').find {|a| a.content == 'people'}.attribute('href').value
|
46
|
+
|
47
|
+
people_file = File.join(site_dir, 'pics', 'people.html')
|
48
|
+
assert File.exist?(people_file)
|
49
|
+
people_doc = Nokogiri::HTML(IO.read(people_file))
|
50
|
+
assert_equal 2, people_doc.css('.entry').size
|
51
|
+
|
52
|
+
['beach.jpg', 'concert.jpg'].each do |pic|
|
53
|
+
assert_equal "../../pics/people/#{pic}", people_doc.css('a').find {|a| a.content == pic}.attribute('href').value
|
54
|
+
end
|
55
|
+
|
56
|
+
# Check that the assets were copied in
|
57
|
+
|
58
|
+
assets_dir = File.join(site.public_dir, 'dropsite', 'dropsite-assets')
|
59
|
+
assert File.exist?(assets_dir)
|
60
|
+
assert File.directory?(assets_dir)
|
61
|
+
simple_index_assets_dir = File.join(assets_dir, 'simple_index')
|
62
|
+
assert File.exist?(simple_index_assets_dir)
|
63
|
+
assert File.directory?(simple_index_assets_dir)
|
64
|
+
assert File.exist?(File.join(simple_index_assets_dir, 'css', 'simple_index.css'))
|
65
|
+
|
66
|
+
# Check that the assets are included correctly
|
67
|
+
|
68
|
+
assert_equal 1, index_doc.css('link').find_all {|l|
|
69
|
+
l.attribute('href').value == 'dropsite/dropsite-assets/simple_index/css/simple_index.css'
|
70
|
+
}.size
|
71
|
+
assert_equal 1, index_doc.css('script').find_all {|l|
|
72
|
+
l.attribute('src').value == 'dropsite/dropsite-assets/simple_index/js/simple_index.js'
|
73
|
+
}.size
|
74
|
+
|
75
|
+
assert_equal 1, pics_doc.css('link').find_all {|l|
|
76
|
+
l.attribute('href').value == 'dropsite-assets/simple_index/css/simple_index.css'
|
77
|
+
}.size
|
78
|
+
assert_equal 1, pics_doc.css('script').find_all {|l|
|
79
|
+
l.attribute('src').value == 'dropsite-assets/simple_index/js/simple_index.js'
|
80
|
+
}.size
|
81
|
+
|
82
|
+
assert_equal 1, people_doc.css('link').find_all {|l|
|
83
|
+
l.attribute('href').value == '../dropsite-assets/simple_index/css/simple_index.css'
|
84
|
+
}.size
|
85
|
+
assert_equal 1, people_doc.css('script').find_all {|l|
|
86
|
+
l.attribute('src').value == '../dropsite-assets/simple_index/js/simple_index.js'
|
87
|
+
}.size
|
88
|
+
end
|
89
|
+
|
90
|
+
protected
|
91
|
+
|
92
|
+
def clean_tmp_dir
|
93
|
+
Dir.entries(TMP_DIR).reject {|e| e =~ /^\./}.each do |entry|
|
94
|
+
file = File.join(TMP_DIR, entry)
|
95
|
+
if File.directory?(file)
|
96
|
+
FileUtils.rm_rf(file)
|
97
|
+
else
|
98
|
+
File.delete(file)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dropsite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: "0.2"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Aaron Royer
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-11-11 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: creates index pages in your Dropbox public directory
|
22
|
+
email: aaronroyer@gmail.com
|
23
|
+
executables:
|
24
|
+
- dropsite
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- bin/dropsite
|
31
|
+
- lib/dropsite/dir_renderer.rb
|
32
|
+
- lib/dropsite/plugins/simple_index/assets/css/reset.css
|
33
|
+
- lib/dropsite/plugins/simple_index/assets/css/simple_index.css
|
34
|
+
- lib/dropsite/plugins/simple_index/assets/images/icons/directory.png
|
35
|
+
- lib/dropsite/plugins/simple_index/assets/images/icons/image.png
|
36
|
+
- lib/dropsite/plugins/simple_index/assets/images/icons/pdf.png
|
37
|
+
- lib/dropsite/plugins/simple_index/assets/images/icons/script.png
|
38
|
+
- lib/dropsite/plugins/simple_index/assets/images/icons/text.png
|
39
|
+
- lib/dropsite/plugins/simple_index/assets/images/icons/unknown.png
|
40
|
+
- lib/dropsite/plugins/simple_index/assets/images/row-bg.png
|
41
|
+
- lib/dropsite/plugins/simple_index/assets/simple_index.js
|
42
|
+
- lib/dropsite/plugins/simple_index/simple_index.erb
|
43
|
+
- lib/dropsite/plugins/simple_index/simple_index.rb
|
44
|
+
- lib/dropsite/plugins.rb
|
45
|
+
- lib/dropsite/render_helper.rb
|
46
|
+
- lib/dropsite/site.rb
|
47
|
+
- lib/dropsite/site_dir.rb
|
48
|
+
- lib/dropsite/site_file.rb
|
49
|
+
- lib/dropsite/site_item.rb
|
50
|
+
- lib/dropsite.rb
|
51
|
+
- test/fixtures/simple_public/file1.txt
|
52
|
+
- test/fixtures/simple_public/file2.txt
|
53
|
+
- test/fixtures/simple_public/pics/leaves.jpg
|
54
|
+
- test/fixtures/simple_public/pics/people/beach.jpg
|
55
|
+
- test/fixtures/simple_public/pics/people/concert.jpg
|
56
|
+
- test/fixtures/simple_public/pics/sculpture.jpg
|
57
|
+
- test/helper.rb
|
58
|
+
- test/test_render_helper.rb
|
59
|
+
- test/test_site.rb
|
60
|
+
- test/test_site_dir.rb
|
61
|
+
- test/test_site_file.rb
|
62
|
+
- test/test_write_site.rb
|
63
|
+
- README
|
64
|
+
- LICENSE
|
65
|
+
- dropsite.gemspec
|
66
|
+
- Rakefile
|
67
|
+
has_rdoc: true
|
68
|
+
homepage: https://rubygems.org/gems/dropsite
|
69
|
+
licenses: []
|
70
|
+
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options:
|
73
|
+
- --line-numbers
|
74
|
+
- --inline-source
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
hash: 3
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 3
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
version: "0"
|
95
|
+
requirements: []
|
96
|
+
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 1.3.7
|
99
|
+
signing_key:
|
100
|
+
specification_version: 3
|
101
|
+
summary: "Dropsite creates a site of interlinked file index pages in the Public directory of your Dropbox. The site created is minimally invasive to your Public directory by only creating one top-level HTML page and one folder, leaving your directories unjunked. BE WARNED: while I _think_ this probably works fine, it is presently considered experimental."
|
102
|
+
test_files:
|
103
|
+
- test/test_render_helper.rb
|
104
|
+
- test/test_site.rb
|
105
|
+
- test/test_site_dir.rb
|
106
|
+
- test/test_site_file.rb
|
107
|
+
- test/test_write_site.rb
|