yuzu 0.2.1.pre
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/.document +5 -0
- data/.yardopts +7 -0
- data/ChangeLog.md +8 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +30 -0
- data/LICENSE.txt +20 -0
- data/README.md +52 -0
- data/Rakefile +62 -0
- data/bin/yuzu +17 -0
- data/docs/About.md +19 -0
- data/docs/GettingStarted.md +48 -0
- data/docs/Reference.md +97 -0
- data/lib/helpers/object.rb +19 -0
- data/lib/helpers/path.rb +296 -0
- data/lib/helpers/string.rb +35 -0
- data/lib/helpers/system_checks.rb +10 -0
- data/lib/helpers/url.rb +64 -0
- data/lib/html/base.rb +187 -0
- data/lib/uploader/base.rb +59 -0
- data/lib/uploader/config.rb +19 -0
- data/lib/uploader/filesystem_service.rb +72 -0
- data/lib/uploader/ftp_service.rb +90 -0
- data/lib/uploader/s3_service.rb +135 -0
- data/lib/uploader/service.rb +57 -0
- data/lib/uploader/suppressor.rb +25 -0
- data/lib/yuzu.rb +6 -0
- data/lib/yuzu/argparse.rb +60 -0
- data/lib/yuzu/command.rb +104 -0
- data/lib/yuzu/commands/base.rb +150 -0
- data/lib/yuzu/commands/create.rb +68 -0
- data/lib/yuzu/commands/generate.rb +95 -0
- data/lib/yuzu/commands/help.rb +20 -0
- data/lib/yuzu/commands/preview.rb +58 -0
- data/lib/yuzu/commands/publish.rb +43 -0
- data/lib/yuzu/commands/stage.rb +62 -0
- data/lib/yuzu/commands/watch.rb +70 -0
- data/lib/yuzu/content/blog_post.rb +45 -0
- data/lib/yuzu/content/sample_project.rb +130 -0
- data/lib/yuzu/core/config.rb +154 -0
- data/lib/yuzu/core/layout.rb +85 -0
- data/lib/yuzu/core/paginated_file.rb +69 -0
- data/lib/yuzu/core/registrar.rb +32 -0
- data/lib/yuzu/core/siteroot.rb +57 -0
- data/lib/yuzu/core/template.rb +158 -0
- data/lib/yuzu/core/updater.rb +123 -0
- data/lib/yuzu/core/visitor.rb +44 -0
- data/lib/yuzu/core/website_base.rb +150 -0
- data/lib/yuzu/core/website_file.rb +270 -0
- data/lib/yuzu/core/website_folder.rb +176 -0
- data/lib/yuzu/filters/base.rb +86 -0
- data/lib/yuzu/filters/catalog.rb +248 -0
- data/lib/yuzu/filters/categories.rb +58 -0
- data/lib/yuzu/filters/currentpath.rb +35 -0
- data/lib/yuzu/filters/description.rb +16 -0
- data/lib/yuzu/filters/extension.rb +16 -0
- data/lib/yuzu/filters/images.rb +32 -0
- data/lib/yuzu/filters/linkroot.rb +35 -0
- data/lib/yuzu/filters/post_date.rb +45 -0
- data/lib/yuzu/filters/post_title.rb +66 -0
- data/lib/yuzu/filters/post_title_removed.rb +28 -0
- data/lib/yuzu/filters/sidebar.rb +26 -0
- data/lib/yuzu/filters/template.rb +16 -0
- data/lib/yuzu/generators/base.rb +44 -0
- data/lib/yuzu/generators/category_folders.rb +91 -0
- data/lib/yuzu/generators/index.rb +108 -0
- data/lib/yuzu/generators/paginate.rb +136 -0
- data/lib/yuzu/postprocessors/all_categories.rb +48 -0
- data/lib/yuzu/postprocessors/base.rb +34 -0
- data/lib/yuzu/postprocessors/contents_without_first_paragraph.rb +20 -0
- data/lib/yuzu/postprocessors/excerpt.rb +23 -0
- data/lib/yuzu/postprocessors/first_paragraph.rb +16 -0
- data/lib/yuzu/postprocessors/pagination.rb +35 -0
- data/lib/yuzu/postprocessors/recent_posts.rb +27 -0
- data/lib/yuzu/postprocessors/thumbnails.rb +48 -0
- data/lib/yuzu/preprocessors/base.rb +71 -0
- data/lib/yuzu/preprocessors/insert_contents.rb +57 -0
- data/lib/yuzu/renderers/base.rb +23 -0
- data/lib/yuzu/renderers/breadcrumb.rb +163 -0
- data/lib/yuzu/renderers/gallery.rb +24 -0
- data/lib/yuzu/renderers/title.rb +21 -0
- data/lib/yuzu/translators/base.rb +57 -0
- data/lib/yuzu/translators/markdown.rb +21 -0
- data/lib/yuzu/translators/plaintext.rb +17 -0
- data/lib/yuzu/version.rb +12 -0
- data/resources/config/compass.rb +6 -0
- data/resources/config/yuzu.yml +166 -0
- data/resources/git/post-commit +42 -0
- data/resources/sample_content/introduction/_snippets/about_insert_contents.md +3 -0
- data/resources/sample_content/introduction/about.md +6 -0
- data/resources/sample_content/introduction/advanced-posts.md +18 -0
- data/resources/sample_content/introduction/blog/blog-folder-is-special.md +8 -0
- data/resources/sample_content/introduction/getting-started.md +14 -0
- data/resources/sample_content/introduction/index.md +6 -0
- data/resources/sample_content/introduction/sample-post.md +13 -0
- data/resources/sample_projects.yml +7 -0
- data/resources/themes/minimal/_sass/print.sass +0 -0
- data/resources/themes/minimal/_sass/screen.sass +81 -0
- data/resources/themes/minimal/_templates/_block.haml +4 -0
- data/resources/themes/minimal/_templates/_blog.haml +3 -0
- data/resources/themes/minimal/_templates/_footer.haml +2 -0
- data/resources/themes/minimal/_templates/_gallery.haml +25 -0
- data/resources/themes/minimal/_templates/_head.haml +12 -0
- data/resources/themes/minimal/_templates/_header.haml +1 -0
- data/resources/themes/minimal/_templates/_menu.haml +6 -0
- data/resources/themes/minimal/_templates/blog.haml +21 -0
- data/resources/themes/minimal/_templates/generic.haml +26 -0
- data/resources/themes/minimal/_templates/home.haml +15 -0
- data/resources/themes/minimal/_templates/index.haml +21 -0
- data/resources/themes/minimal/css/print.css +0 -0
- data/resources/themes/minimal/css/screen.css +133 -0
- data/resources/themes/minimal/img/favicon.png +0 -0
- data/resources/yard/default/fulldoc/html/css/common.css +16 -0
- data/test/helper.rb +18 -0
- data/test/test_yuzu.rb +8 -0
- data/yuzu.gemspec +182 -0
- metadata +302 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
unless String.method_defined?(:titlecase)
|
|
3
|
+
|
|
4
|
+
class String
|
|
5
|
+
def titlecase
|
|
6
|
+
self.downcase.spacify.split(" ").collect {|str| str.capitalize}.join(" ")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def titleize
|
|
10
|
+
titlecase
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def spacify
|
|
14
|
+
self.gsub("-", " ").gsub("_", " ")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def dasherize
|
|
18
|
+
self.gsub(" ", "-").gsub("_", "-")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def underline
|
|
22
|
+
self.gsub(/\W/, "_")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def includes_one_of?(arr)
|
|
26
|
+
tr = false
|
|
27
|
+
arr.each do |el|
|
|
28
|
+
tr ||= self.include?(el)
|
|
29
|
+
end
|
|
30
|
+
tr
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
data/lib/helpers/url.rb
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Url holds an abstraction for web URLs, closely tied to the Path objects. This aids in translating
|
|
2
|
+
# on-disk paths to URLs for links.
|
|
3
|
+
module Helpers
|
|
4
|
+
|
|
5
|
+
class Url
|
|
6
|
+
# Create a new Url object.
|
|
7
|
+
#
|
|
8
|
+
# @param [String, Path] url_path The root path of the Url, from the file system, with the
|
|
9
|
+
# appropriate extension in place ideally.
|
|
10
|
+
# @param [String] prefix A prefix to add to the front of the url. This usually consists of the
|
|
11
|
+
# root common path on the server like http://domain.com/blah
|
|
12
|
+
def initialize(url_path, prefix=nil)
|
|
13
|
+
if url_path.is_a?(Path)
|
|
14
|
+
@path = url_path
|
|
15
|
+
|
|
16
|
+
elsif url_path.is_a?(String)
|
|
17
|
+
@path = Path.new(url_path)
|
|
18
|
+
|
|
19
|
+
elsif url_path.is_a?(Url)
|
|
20
|
+
@path = url_path.path
|
|
21
|
+
|
|
22
|
+
else
|
|
23
|
+
raise "Url must be initialized with a String, Url, or Path instance."
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
@prefix = prefix
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_accessor :path
|
|
31
|
+
|
|
32
|
+
def + (other)
|
|
33
|
+
if other.is_a?(String)
|
|
34
|
+
Url.new(@path + other, prefix=@prefix)
|
|
35
|
+
|
|
36
|
+
elsif other.is_a?(Url)
|
|
37
|
+
Url.new(@path + other.path.relative, prefix=@prefix)
|
|
38
|
+
|
|
39
|
+
elsif other.is_a?(Path)
|
|
40
|
+
Url.new(@path + other.relative_path, prefix=@prefix)
|
|
41
|
+
|
|
42
|
+
else
|
|
43
|
+
raise "Url + accepts String, Path, and Url instances."
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_s
|
|
49
|
+
full
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def full(new_extension=nil)
|
|
53
|
+
new_extension.nil? ? join(@prefix, @path) : join(@prefix, @path.with_extension(new_extension))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Join a set of paths together
|
|
57
|
+
def join(prefix, path, suffix=nil)
|
|
58
|
+
root = prefix.nil? ? path.relative : prefix + "/" + path.relative
|
|
59
|
+
suffix.nil? ? root : root + "/" + suffix
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
data/lib/html/base.rb
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Html provides a concise way of programmatically expressing HTML tags and structure.
|
|
2
|
+
#
|
|
3
|
+
# This enables one to express a list like this:
|
|
4
|
+
#
|
|
5
|
+
# Html::UnorderedList.new << (Html::ListItem.new << "first") + (Html::ListItem.new << "second")
|
|
6
|
+
#
|
|
7
|
+
# which results in:
|
|
8
|
+
#
|
|
9
|
+
# <ul><li>first</li><li>second</li></ul>
|
|
10
|
+
#
|
|
11
|
+
# The << operator means "contains", and reduces an Html object and a string to another string. So
|
|
12
|
+
# after the << operation, the tags just obey String semantics.
|
|
13
|
+
#
|
|
14
|
+
# Commonly used nested tags can be composited and deployed as templates multiple times.
|
|
15
|
+
#
|
|
16
|
+
# title_link = Html::H1.new << Html::Link(:href => "http://mysite.com")
|
|
17
|
+
# title_link << "My Site"
|
|
18
|
+
#
|
|
19
|
+
# which results in:
|
|
20
|
+
#
|
|
21
|
+
# <h1><a href="http://mysite.com">My Site</a></h1>
|
|
22
|
+
#
|
|
23
|
+
# This is seemingly more verbose that writing it directly, but it enables you to write HTML without
|
|
24
|
+
# having to do string interpolation and concatenation, and it doesn't imbue Ruby code with a lot of
|
|
25
|
+
# HTML-related strings.
|
|
26
|
+
#
|
|
27
|
+
# words = %w(hello doctor name continue yesterday tomorrow)
|
|
28
|
+
# Html::UnorderedList.new << words.collect {|w| Html::ListItem.new(:class => "class-#{w}") << w}.join
|
|
29
|
+
#
|
|
30
|
+
# which will yield:
|
|
31
|
+
#
|
|
32
|
+
# <ul>
|
|
33
|
+
# <li class="class-hello">hello</li>
|
|
34
|
+
# <li class="class-doctor">doctor</li>
|
|
35
|
+
# <li class="class-name">name</li>
|
|
36
|
+
# <li class="class-continue">continue</li>
|
|
37
|
+
# <li class="class-yesterday">yesterday</li>
|
|
38
|
+
# <li class="class-tomorrow">tomorrow</li>
|
|
39
|
+
# </ul>
|
|
40
|
+
|
|
41
|
+
module Html
|
|
42
|
+
# The base Html class provides functionality for wrapping HTML tags, e.g. <div>...</div>
|
|
43
|
+
class Base
|
|
44
|
+
def initialize(attr={})
|
|
45
|
+
@attr = attr
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@tag = "div"
|
|
49
|
+
def self.tag
|
|
50
|
+
@tag
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def tag
|
|
54
|
+
self.class.tag
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def attributes
|
|
58
|
+
@attr.length == 0 ? "" : @attr.collect {|key, value| " #{key.to_s}='#{value}'"}.join
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def processed_output(contents)
|
|
62
|
+
"<#{tag}#{attributes}>#{contents}</#{tag}>"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def << (other)
|
|
66
|
+
if other.is_a?(String)
|
|
67
|
+
processed_output(other)
|
|
68
|
+
else
|
|
69
|
+
Composite.new(self, other)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Class that sets off the tag by newlines to aid in readability for raw output.
|
|
75
|
+
class Container < Base
|
|
76
|
+
def processed_output(contents)
|
|
77
|
+
"\n<#{tag}#{attributes}>\n#{contents}\n</#{tag}>\n"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class Item < Base
|
|
82
|
+
def processed_output(contents)
|
|
83
|
+
"<#{tag}#{attributes}>#{contents}</#{tag}>\n"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Class for compositing nested tags togther and using them multiple times in different contexts.
|
|
88
|
+
class Composite
|
|
89
|
+
def initialize(first, second)
|
|
90
|
+
@first = first
|
|
91
|
+
@second = second
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def << (other)
|
|
95
|
+
if other.is_a?(String)
|
|
96
|
+
@first << (@second << other)
|
|
97
|
+
else
|
|
98
|
+
Composite.new(self, other)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# HTML flags are those that don't have a closing tag, e.g. <img href="">
|
|
104
|
+
class Flag < Base
|
|
105
|
+
def to_s
|
|
106
|
+
"<#{tag}#{attributes}>"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def << (other)
|
|
110
|
+
self.to_s + other
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Handler for adding HTML comments inline.
|
|
115
|
+
class Comment < Base
|
|
116
|
+
def << (other)
|
|
117
|
+
"\n<!-- #{other} -->\n"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Class handler for <div> tags.
|
|
122
|
+
class Div < Container
|
|
123
|
+
instance_variable_set(:@tag, "div")
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Class handler for <a> links.
|
|
127
|
+
class Link < Base
|
|
128
|
+
instance_variable_set(:@tag, "a")
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Class handler for <li> list item tags.
|
|
132
|
+
class ListItem < Item
|
|
133
|
+
instance_variable_set(:@tag, "li")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Class handler for <ul> unordered lists.
|
|
137
|
+
class UnorderedList < Container
|
|
138
|
+
instance_variable_set(:@tag, "ul")
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Handler for <ol> ordered lists.
|
|
142
|
+
class OrderedList < Container
|
|
143
|
+
instance_variable_set(:@tag, "ol")
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Handler for <h1> headers.
|
|
147
|
+
class H1 < Item
|
|
148
|
+
instance_variable_set(:@tag, "h1")
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Handler for <h2> headers.
|
|
152
|
+
class H2 < Item
|
|
153
|
+
instance_variable_set(:@tag, "h2")
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Handler for <h3> headers.
|
|
157
|
+
class H3 < Item
|
|
158
|
+
instance_variable_set(:@tag, "h3")
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Handler for <h4> headers.
|
|
162
|
+
class H4 < Item
|
|
163
|
+
instance_variable_set(:@tag, "h4")
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Handler for <span> tags.
|
|
167
|
+
class Span < Base
|
|
168
|
+
instance_variable_set(:@tag, "span")
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Handler for <p> paragraph tags.
|
|
172
|
+
class Paragraph < Container
|
|
173
|
+
instance_variable_set(:@tag, "p")
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Handler for <img> images.
|
|
177
|
+
class Image < Flag
|
|
178
|
+
instance_variable_set(:@tag, "img")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Handler for <br> line breaks.
|
|
182
|
+
class Break < Flag
|
|
183
|
+
instance_variable_set(:@tag, "br")
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
end
|
|
187
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Require service.rb first.
|
|
2
|
+
require 'uploader/service'
|
|
3
|
+
require 'uploader/suppressor'
|
|
4
|
+
require 'uploader/config'
|
|
5
|
+
|
|
6
|
+
Dir["#{File.dirname(__FILE__)}/*"].each do |service|
|
|
7
|
+
require service if service.include?("_service")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
module Uploader
|
|
12
|
+
class UnrecognizedService < Exception; end
|
|
13
|
+
|
|
14
|
+
class UploadManager
|
|
15
|
+
|
|
16
|
+
def initialize(config, service_override=nil)
|
|
17
|
+
@config = config # UploaderConfig
|
|
18
|
+
@service_override = service_override
|
|
19
|
+
@suppressor = Suppressor.new
|
|
20
|
+
|
|
21
|
+
set_service!
|
|
22
|
+
connect!
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def set_service!
|
|
26
|
+
service_name, service_class = get_service
|
|
27
|
+
service_config_hash = @config.send(service_name).merge({:verbose? => @config.verbose?})
|
|
28
|
+
|
|
29
|
+
@service = service_class.new(UploaderConfig.new(service_config_hash))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def get_service
|
|
33
|
+
service_key = (@service_override || @config.connection).to_sym
|
|
34
|
+
|
|
35
|
+
if Service.is_registered?(service_key)
|
|
36
|
+
$stderr.puts "Using service #{service_key}" if @config.verbose?
|
|
37
|
+
|
|
38
|
+
return service_key, Service.services[service_key]
|
|
39
|
+
else
|
|
40
|
+
raise UnrecognizedService
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def connect!
|
|
45
|
+
@service.connect!
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def upload(remote_path, contents)
|
|
49
|
+
@service.upload(remote_path, contents)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def close!
|
|
53
|
+
@service.close!
|
|
54
|
+
@suppressor.close!
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
module Uploader
|
|
3
|
+
|
|
4
|
+
class UploaderConfig
|
|
5
|
+
def initialize(config_hash)
|
|
6
|
+
@config_hash = config_hash
|
|
7
|
+
|
|
8
|
+
(class << self; self; end).class_eval do
|
|
9
|
+
config_hash.each_pair do |key, value|
|
|
10
|
+
define_method(key) do
|
|
11
|
+
value
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'uploader/base'
|
|
2
|
+
require 'uploader/service'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
module Uploader
|
|
7
|
+
GREEN = "\033[32m"
|
|
8
|
+
ENDC = "\033[0m"
|
|
9
|
+
|
|
10
|
+
class FileSystemService < Service
|
|
11
|
+
def connect!
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def upload(remote_path, contents)
|
|
15
|
+
raise UploadArgumentError if not remote_path.is_a?(Path)
|
|
16
|
+
|
|
17
|
+
contents_to_upload, binmode = get_upload_contents(contents)
|
|
18
|
+
|
|
19
|
+
copy_contents_to_file_system(remote_path, contents_to_upload, binmode)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def get_upload_contents(contents)
|
|
23
|
+
binmode = false
|
|
24
|
+
if contents.is_a?(File)
|
|
25
|
+
contents_to_upload = contents.read
|
|
26
|
+
binmode = true
|
|
27
|
+
|
|
28
|
+
elsif contents.is_a?(String)
|
|
29
|
+
contents_to_upload = contents
|
|
30
|
+
|
|
31
|
+
else
|
|
32
|
+
raise UnrecognizedContentType
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
return contents_to_upload, binmode
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def copy_contents_to_file_system(remote_path, contents, binary=true)
|
|
39
|
+
destination = Path.new(@config.destination) + remote_path.relative
|
|
40
|
+
if @config.verbose?
|
|
41
|
+
$stderr.puts %Q{Copying #{GREEN}#{remote_path}#{ENDC} to the file system
|
|
42
|
+
--> #{destination}}
|
|
43
|
+
else
|
|
44
|
+
$stderr.print "."
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
begin
|
|
48
|
+
f = File.open(destination.absolute, "w+")
|
|
49
|
+
|
|
50
|
+
rescue => detail
|
|
51
|
+
$stderr.puts detail.message
|
|
52
|
+
$stderr.puts "Attempting to create the path."
|
|
53
|
+
|
|
54
|
+
# Assume the directories leading to the file don't exist. Create them.
|
|
55
|
+
FileUtils::mkdir_p(destination.dirname)
|
|
56
|
+
|
|
57
|
+
f = File.open(destination.absolute, "w+")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
unless f.nil?
|
|
61
|
+
f.syswrite(contents)
|
|
62
|
+
f.close
|
|
63
|
+
$stderr.puts "Done with #{destination.relative}." if @config.verbose?
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
Service.register(:filesystem => FileSystemService)
|
|
69
|
+
Service.register(:stage => FileSystemService)
|
|
70
|
+
Service.register(:preview => FileSystemService)
|
|
71
|
+
end
|
|
72
|
+
|