alula 0.2.3 → 0.4.0b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. data/.gitignore +2 -0
  2. data/Gemfile +7 -0
  3. data/Guardfile +9 -0
  4. data/Rakefile +12 -1
  5. data/VERSION +1 -1
  6. data/alula.gemspec +20 -4
  7. data/lib/alula/attachment_processor.rb +77 -0
  8. data/lib/alula/cdn.rb +30 -0
  9. data/lib/alula/cdns/edgecast.rb +16 -0
  10. data/lib/alula/cdns/hosts.rb +14 -0
  11. data/lib/alula/cli.rb +90 -39
  12. data/lib/alula/compressors.rb +22 -10
  13. data/lib/alula/config.rb +141 -0
  14. data/lib/alula/content.rb +113 -0
  15. data/lib/alula/contents/attachment.rb +8 -0
  16. data/lib/alula/contents/item.rb +409 -0
  17. data/lib/alula/contents/metadata.rb +73 -0
  18. data/lib/alula/contents/page.rb +9 -0
  19. data/lib/alula/contents/post.rb +32 -0
  20. data/lib/alula/context.rb +72 -0
  21. data/lib/alula/core_ext.rb +5 -0
  22. data/lib/alula/core_ext/environment.rb +20 -0
  23. data/lib/alula/core_ext/filter.rb +20 -0
  24. data/lib/alula/core_ext/filters/smilies.rb +36 -0
  25. data/lib/alula/core_ext/manifest.rb +30 -0
  26. data/lib/alula/core_ext/tag.rb +100 -0
  27. data/lib/alula/core_ext/tags/attachment.rb +28 -0
  28. data/lib/alula/core_ext/tags/blockquote.rb +21 -0
  29. data/lib/alula/core_ext/tags/image.rb +48 -0
  30. data/lib/alula/core_ext/tags/locale.rb +17 -0
  31. data/lib/alula/core_ext/tags/video.rb +103 -0
  32. data/lib/alula/generator.rb +31 -0
  33. data/lib/alula/generators/feedbuilder.rb +44 -0
  34. data/lib/alula/generators/paginate.rb +88 -0
  35. data/lib/alula/generators/sitemap.rb +26 -0
  36. data/lib/alula/helpers.rb +2 -0
  37. data/lib/alula/helpers/addons.rb +12 -0
  38. data/lib/alula/helpers/assets.rb +56 -0
  39. data/lib/alula/helpers/url_helpers.rb +16 -0
  40. data/lib/alula/plugin.rb +32 -0
  41. data/lib/alula/processor.rb +86 -0
  42. data/lib/alula/processors/dummy.rb +24 -0
  43. data/lib/alula/processors/image.rb +52 -0
  44. data/lib/alula/processors/magick.rb +83 -0
  45. data/lib/alula/processors/video.rb +97 -0
  46. data/lib/alula/processors/zencoder.rb +199 -0
  47. data/lib/alula/progress.rb +95 -0
  48. data/lib/alula/progressbar.rb +66 -0
  49. data/lib/alula/site.rb +331 -262
  50. data/lib/alula/storage.rb +46 -0
  51. data/lib/alula/storages/file_item.rb +43 -0
  52. data/lib/alula/storages/filestorage.rb +96 -0
  53. data/lib/alula/storages/item.rb +12 -0
  54. data/lib/alula/support/commonlogger.rb +30 -0
  55. data/lib/alula/theme.rb +70 -13
  56. data/lib/alula/theme/layout.rb +56 -0
  57. data/lib/alula/theme/view.rb +43 -0
  58. data/lib/alula/version.rb +1 -1
  59. data/locales/en.yml +9 -0
  60. data/locales/fi.yml +10 -0
  61. data/locales/l10n/ar.yml +199 -0
  62. data/locales/l10n/az.yml +199 -0
  63. data/locales/l10n/bg.yml +199 -0
  64. data/locales/l10n/bn-IN.yml +182 -0
  65. data/locales/l10n/bs.yml +242 -0
  66. data/locales/l10n/ca.yml +199 -0
  67. data/locales/l10n/cs.yml +198 -0
  68. data/locales/l10n/csb.yml +210 -0
  69. data/locales/l10n/cy.yml +199 -0
  70. data/locales/l10n/da.yml +199 -0
  71. data/locales/l10n/de-AT.yml +203 -0
  72. data/locales/l10n/de-CH.yml +203 -0
  73. data/locales/l10n/de.yml +203 -0
  74. data/locales/l10n/dsb.yml +215 -0
  75. data/locales/l10n/el.yml +199 -0
  76. data/locales/l10n/en-AU.yml +205 -0
  77. data/locales/l10n/en-CA.yml +214 -0
  78. data/locales/l10n/en-GB.yml +205 -0
  79. data/locales/l10n/en-IN.yml +205 -0
  80. data/locales/l10n/en-US.yml +205 -0
  81. data/locales/l10n/en.yml +205 -0
  82. data/locales/l10n/eo.yml +201 -0
  83. data/locales/l10n/es-AR.yml +205 -0
  84. data/locales/l10n/es-CL.yml +199 -0
  85. data/locales/l10n/es-CO.yml +205 -0
  86. data/locales/l10n/es-MX.yml +205 -0
  87. data/locales/l10n/es-PE.yml +181 -0
  88. data/locales/l10n/es-VE.yml +205 -0
  89. data/locales/l10n/es.yml +199 -0
  90. data/locales/l10n/et.yml +199 -0
  91. data/locales/l10n/eu.yml +199 -0
  92. data/locales/l10n/fa.yml +199 -0
  93. data/locales/l10n/fi.yml +199 -0
  94. data/locales/l10n/fr-CA.yml +207 -0
  95. data/locales/l10n/fr-CH.yml +207 -0
  96. data/locales/l10n/fr.yml +222 -0
  97. data/locales/l10n/fur.yml +199 -0
  98. data/locales/l10n/gl-ES.yml +178 -0
  99. data/locales/l10n/gsw-CH.yml +199 -0
  100. data/locales/l10n/he.yml +201 -0
  101. data/locales/l10n/hi-IN.yml +199 -0
  102. data/locales/l10n/hi.yml +199 -0
  103. data/locales/l10n/hr.yml +237 -0
  104. data/locales/l10n/hsb.yml +214 -0
  105. data/locales/l10n/hu.yml +199 -0
  106. data/locales/l10n/id.yml +200 -0
  107. data/locales/l10n/is.yml +213 -0
  108. data/locales/l10n/it.yml +205 -0
  109. data/locales/l10n/ja.yml +197 -0
  110. data/locales/l10n/kn.yml +199 -0
  111. data/locales/l10n/ko.yml +197 -0
  112. data/locales/l10n/lo.yml +186 -0
  113. data/locales/l10n/lt.yml +182 -0
  114. data/locales/l10n/lv.yml +215 -0
  115. data/locales/l10n/mk.yml +170 -0
  116. data/locales/l10n/mn.yml +205 -0
  117. data/locales/l10n/nb.yml +207 -0
  118. data/locales/l10n/nl.yml +199 -0
  119. data/locales/l10n/nn.yml +160 -0
  120. data/locales/l10n/pl.yml +221 -0
  121. data/locales/l10n/pt-BR.yml +207 -0
  122. data/locales/l10n/pt-PT.yml +207 -0
  123. data/locales/l10n/quotes.yml +24 -0
  124. data/locales/l10n/rm.yml +182 -0
  125. data/locales/l10n/ro.yml +199 -0
  126. data/locales/l10n/ru.yml +257 -0
  127. data/locales/l10n/sk.yml +213 -0
  128. data/locales/l10n/sl.yml +210 -0
  129. data/locales/l10n/sr-Latn.yml +170 -0
  130. data/locales/l10n/sr.yml +170 -0
  131. data/locales/l10n/sv-SE.yml +199 -0
  132. data/locales/l10n/sw.yml +197 -0
  133. data/locales/l10n/th.yml +173 -0
  134. data/locales/l10n/tl.yml +229 -0
  135. data/locales/l10n/tr.yml +199 -0
  136. data/locales/l10n/uk.yml +257 -0
  137. data/locales/l10n/vi.yml +201 -0
  138. data/locales/l10n/wo.yml +205 -0
  139. data/locales/l10n/zh-CN.yml +199 -0
  140. data/locales/l10n/zh-TW.yml +199 -0
  141. data/template/Gemfile.erb +14 -4
  142. data/template/README +16 -0
  143. data/template/config.yml.erb +42 -38
  144. data/test/fixtures/config_001_simple.yml +2 -0
  145. data/test/fixtures/config_002_l10n.yml +5 -0
  146. data/test/fixtures/pages/invalid-page.markdown +1 -0
  147. data/test/fixtures/pages/multilingual-page.markdown +20 -0
  148. data/test/fixtures/pages/section/subpage.markdown +5 -0
  149. data/test/fixtures/pages/simple-page.markdown +7 -0
  150. data/test/fixtures/posts/2012-07-02-invalid-post.markdown +1 -0
  151. data/test/fixtures/posts/2012-07-02-simple.markdown +7 -0
  152. data/test/fixtures/posts/2012-07-03-full-metadata.markdown +8 -0
  153. data/test/fixtures/posts/2012-07-03-multilingual-full-metadata.markdown +20 -0
  154. data/test/fixtures/theme/test/layouts/default.html.erb +1 -0
  155. data/test/fixtures/theme/test/views/page.html.erb +1 -0
  156. data/test/fixtures/theme/test/views/post.html.erb +1 -0
  157. data/test/minitest_helper.rb +14 -0
  158. data/test/test_config.rb +33 -0
  159. data/test/test_content.rb +30 -0
  160. data/test/test_metadata.rb +83 -0
  161. data/test/test_page.rb +81 -0
  162. data/test/test_post.rb +123 -0
  163. data/test/test_storage.rb +23 -0
  164. data/test/test_storage_file.rb +32 -0
  165. data/test/test_theme.rb +45 -0
  166. data/vendor/assets/images/favicon.png +0 -0
  167. data/vendor/assets/images/grey.gif +0 -0
  168. data/vendor/assets/javascripts/jquery.alula.js.coffee +16 -0
  169. data/vendor/{javascripts → assets/javascripts}/jquery.js +0 -0
  170. data/vendor/assets/javascripts/jquery.lazyload.js +210 -0
  171. data/vendor/assets/javascripts/lazyload.js.coffee +15 -0
  172. data/vendor/layouts/feed.xml.builder +19 -0
  173. data/vendor/layouts/sitemap.xml.builder +10 -0
  174. data/vendor/views/feed_post.html.haml +1 -0
  175. metadata +529 -50
  176. data/lib/alula.rb +0 -5
  177. data/lib/alula/assethelper.rb +0 -75
  178. data/lib/alula/plugins.rb +0 -23
  179. data/lib/alula/plugins/assets.rb +0 -82
  180. data/lib/alula/plugins/pagination.rb +0 -121
  181. data/lib/alula/rake_tasks.rb +0 -42
  182. data/lib/alula/tasks.rb +0 -2
@@ -1,5 +0,0 @@
1
- require "alula/version"
2
-
3
- module Alula
4
- # Your code goes here...
5
- end
@@ -1,75 +0,0 @@
1
- require 'RMagick'
2
-
3
- module Alula
4
- class AssetHelper
5
- IMAGES = %w{jpeg jpg png gif}
6
- MOVIES = %w{mp4}
7
-
8
- def initialize(asset_path, options)
9
- @options = options
10
- @asset_path = asset_path
11
- end
12
-
13
- def process(asset, options)
14
- options = @options.deep_merge(options)
15
-
16
- # Resolve our asset type
17
- ext = File.extname(asset)[1..-1].downcase
18
-
19
- if IMAGES.include?(ext)
20
- [:image, process_image(asset, options)]
21
- elsif MOVIES.include?(ext)
22
- [:movie, process_movie(asset, options)]
23
- else
24
- raise "Unknown asset type #{ext} for #{asset}"
25
- end
26
- end
27
-
28
- private
29
- def process_image(asset, options)
30
- ext = File.extname(asset)[1..-1].downcase
31
- name = File.basename(asset, ext).to_url
32
- generated = []
33
-
34
- # Resolve size for new photo
35
- width, height = case options[:type]
36
- when :attachment
37
- options["images"]["size"].split("x").collect {|i| i.to_i }
38
- when :thumbnail
39
- options["images"]["thumbnails"].split("x").collect {|i| i.to_i }
40
- end
41
-
42
- file_path = case options[:type]
43
- when :attachment
44
- File.join("attachments", "_generated", "images", @asset_path)
45
- when :thumbnail
46
- File.join("attachments", "_generated", "thumbnails", @asset_path)
47
- end
48
- # Create output path
49
- FileUtils.mkdir_p(file_path)
50
-
51
- # Copy asset to originals
52
- if options[:type] == :attachment and !File.exists?(File.join("attachments", "originals", @asset_path, "#{name}.#{ext}"))
53
- FileUtils.mkdir_p File.join("attachments", "originals", @asset_path)
54
- FileUtils.cp asset, File.join("attachments", "originals", @asset_path, "#{name}.#{ext}")
55
- end
56
-
57
- # Create normal photo
58
- image = Magick::Image.read(asset).first
59
- image_width, image_height = image.columns, image.rows
60
-
61
- resized = image.resize_to_fit(width, height)
62
- resized.write(File.join(file_path, "#{name}.#{ext}"))
63
- generated << File.join(@asset_path, "#{name}.#{ext}")
64
-
65
- # Generate retina if required
66
- if (options["images"]["retina"] and (image_width > width * 2) or (image_height > height * 2))
67
- retina = image.resize_to_fit(width * 2, height * 2)
68
- resized.write(File.join(file_path, "#{name}_2x.#{ext}"))
69
- generated << File.join(@asset_path, "#{name}_2x.#{ext}")
70
- end
71
-
72
- return generated
73
- end
74
- end
75
- end
@@ -1,23 +0,0 @@
1
- module Alula
2
- module Plugins
3
- # def self.register(plugin, path)
4
- # @@plugins ||= {}
5
- # @@plugins[plugin] = path
6
- # end
7
- #
8
- # def self.plugins
9
- # @@plugins
10
- # end
11
- def self.register_attachment_handler(type, handler)
12
- @@handlers ||= {}
13
- @@handlers[:attachment] ||= {}
14
- @@handlers[:attachment][type] = handler
15
- end
16
-
17
- def self.attachment_handler(type)
18
- @@handlers ||= {}
19
- @@handlers[:attachment] ||= {}
20
- @@handlers[:attachment][type]
21
- end
22
- end
23
- end
@@ -1,82 +0,0 @@
1
- module Alula
2
- module Plugins
3
- class GenericAsset < Liquid::Tag
4
- def self.type(type)
5
- define_method(:type) { type }
6
- end
7
-
8
- def self.default(default)
9
- define_method(:default) { default }
10
- end
11
-
12
- def initialize(tag_name, markup, tokens)
13
- super
14
-
15
- /(?<name>\w+)/ =~ markup
16
- @name = "#{name || default}.#{type}"
17
- end
18
-
19
- def render(context)
20
- asset_path = context.registers[:site].config["asset_path"]
21
- manifest = context.registers[:site].config["manifest"]
22
-
23
- content(File.join(asset_path, manifest.assets[@name]))
24
- end
25
- end
26
-
27
- class StylesheetAsset < GenericAsset
28
- type :css
29
- default :styles
30
-
31
- def content(asset)
32
- "<link rel=\"stylesheet\" href=\"#{asset}\" media=\"screen,projection\" type=\"text/css\">"
33
- end
34
- end
35
-
36
- class JavascriptAsset < GenericAsset
37
- type :js
38
- default "scripts"
39
-
40
- def content(asset)
41
- if File.size(File.join("public", asset)) < 10
42
- content = File.read(File.join("public", asset))
43
- unless content == ";"
44
- "<script type=\"text/javascript\">#{content}</script>"
45
- end
46
- else
47
- "<script type=\"text/javascript\" src=\"#{asset}\"></script>"
48
- end
49
- end
50
- end
51
-
52
- class ImageAsset < GenericAsset
53
- def initialize(tag_name, markup, tokens)
54
- /(?<src>(?:https?:\/\/|\/|\S+\/)\S+)(?<title>\s+.+)/ =~ markup
55
- /(?:"|')(?<title>[^"']+)?(?:"|')\s+(?:"|')(?<alt>[^"']+)?(?:"|')/ =~ title
56
-
57
- @name = src
58
- @title = title
59
- @alt = alt
60
- end
61
-
62
- def render(context)
63
- asset_path = context.registers[:site].config["asset_path"]
64
- manifest = context.registers[:site].config["manifest"]
65
-
66
- asset = File.join(asset_path, manifest.assets[@name])
67
-
68
- # Fetch image size
69
- img = Magick::Image.read(File.join("public", asset)).first
70
- width = img.columns
71
- height = img.rows
72
-
73
- "<img src=\"#{asset}\" alt=\"#{@alt}\" title=\"#{@title}\" width=\"#{width}\" height=\"#{height}\">"
74
- end
75
- end
76
- end
77
- end
78
-
79
-
80
- Liquid::Template.register_tag('stylesheet_link', Alula::Plugins::StylesheetAsset)
81
- Liquid::Template.register_tag('javascript_link', Alula::Plugins::JavascriptAsset)
82
- Liquid::Template.register_tag('image', Alula::Plugins::ImageAsset)
@@ -1,121 +0,0 @@
1
- module Jekyll
2
-
3
- class Pagination < Generator
4
- # This generator is safe from arbitrary code execution.
5
- safe true
6
-
7
- # Generate paginated pages if necessary.
8
- #
9
- # site - The Site.
10
- #
11
- # Returns nothing.
12
- def generate(site)
13
- site.pages.dup.each do |page|
14
- paginate(site, page) if Pager.pagination_enabled?(site.config, page)
15
- end
16
- end
17
-
18
- # Paginates the blog's posts. Renders the index.html file into paginated
19
- # directories, e.g.: page2/index.html, page3/index.html, etc and adds more
20
- # site-wide data.
21
- #
22
- # site - The Site.
23
- # page - The index.html Page that requires pagination.
24
- #
25
- # {"paginator" => { "page" => <Number>,
26
- # "per_page" => <Number>,
27
- # "posts" => [<Post>],
28
- # "total_posts" => <Number>,
29
- # "total_pages" => <Number>,
30
- # "previous_page" => <Number>,
31
- # "next_page" => <Number> }}
32
- def paginate(site, page)
33
- all_posts = site.site_payload['site']['posts']
34
- pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
35
- page_dir = page.destination('').sub(/\/[^\/]+$/, '')
36
- page_dir_config = site.config['pagination_dir']
37
- dir = ((page_dir_config || page_dir) + '/').sub(/^\/+/, '')
38
-
39
- (1..pages).each do |num_page|
40
- pager = Pager.new(site.config, num_page, all_posts, page_dir+'/', '/'+dir, pages)
41
- if num_page > 1
42
- newpage = Page.new(site, site.source, page_dir, page.name)
43
- newpage.pager = pager
44
- newpage.dir = File.join(page.dir, "#{dir}page/#{num_page}")
45
- site.pages << newpage
46
- else
47
- page.pager = pager
48
- end
49
- end
50
- end
51
- end
52
-
53
- class Pager
54
- attr_reader :page, :per_page, :posts, :total_posts, :total_pages, :previous_page, :next_page
55
-
56
- # Calculate the number of pages.
57
- #
58
- # all_posts - The Array of all Posts.
59
- # per_page - The Integer of entries per page.
60
- #
61
- # Returns the Integer number of pages.
62
- def self.calculate_pages(all_posts, per_page)
63
- (all_posts.size.to_f / per_page.to_i).ceil
64
- end
65
-
66
- # Determine if pagination is enabled for a given file.
67
- #
68
- # config - The configuration Hash.
69
- # file - The String filename of the file.
70
- #
71
- # Returns true if pagination is enabled, false otherwise.
72
- def self.pagination_enabled?(config, file)
73
- file.name == 'index.html' && !config['paginate'].nil? && file.content =~ /paginator\./
74
- end
75
-
76
- # Initialize a new Pager.
77
- #
78
- # config - The Hash configuration of the site.
79
- # page - The Integer page number.
80
- # all_posts - The Array of all the site's Posts.
81
- # num_pages - The Integer number of pages or nil if you'd like the number
82
- # of pages calculated.
83
- def initialize(config, page, all_posts, index_dir, pagination_dir, num_pages = nil)
84
- @page = page
85
- @per_page = config['paginate'].to_i
86
- @page_dir = pagination_dir + 'page/'
87
- @total_pages = num_pages || Pager.calculate_pages(all_posts, @per_page)
88
- @previous_page = nil
89
-
90
- if @page > @total_pages
91
- raise RuntimeError, "page number can't be greater than total pages: #{@page} > #{@total_pages}"
92
- end
93
-
94
- init = (@page - 1) * @per_page
95
- offset = (init + @per_page - 1) >= all_posts.size ? all_posts.size : (init + @per_page - 1)
96
-
97
- @total_posts = all_posts.size
98
- @posts = all_posts[init..offset]
99
- @previous_page = @page != 1 ? @page_dir + (@page - 1).to_s + '/' : nil
100
- @previous_page = index_dir if @page - 1 == 1
101
- @next_page = @page != @total_pages ? @page_dir + (@page + 1).to_s + '/' : nil
102
- end
103
-
104
- # Convert this Pager's data to a Hash suitable for use by Liquid.
105
- #
106
- # Returns the Hash representation of this Pager.
107
- def to_liquid
108
- {
109
- 'page' => page,
110
- 'per_page' => per_page,
111
- 'posts' => posts,
112
- 'total_posts' => total_posts,
113
- 'total_pages' => total_pages,
114
- 'previous_page' => previous_page,
115
- 'next_page' => next_page
116
- }
117
- end
118
- end
119
-
120
- end
121
-
@@ -1,42 +0,0 @@
1
- require 'alula/site'
2
-
3
- module Alula
4
- class RakeTasks
5
- include Rake::DSL if defined? Rake::DSL
6
-
7
- def self.install_tasks
8
- self.new().install
9
- end
10
-
11
- def initialize
12
- end
13
-
14
- def install
15
- desc "Generate Alula blog (development)"
16
- task :generate do
17
- puts "==> Generating blog..."
18
- site = Alula::Site.new
19
- site.generate
20
- end
21
-
22
- desc "Starts previw mode by development server"
23
- task :preview do
24
- puts "==> Starting preview"
25
- site = Alula::Site.new
26
- site.preview
27
- end
28
-
29
- desc "Generate blog (deployment)"
30
- task :publish do
31
- site = Alula::Site.new("asset_compress" => true)
32
- site.generate
33
- end
34
-
35
- desc "Starts preview server in deployment mode"
36
- task :preview_publish do
37
- site = Alula::Site.new("asset_compress" => true)
38
- site.preview
39
- end
40
- end
41
- end
42
- end
@@ -1,2 +0,0 @@
1
- require 'alula/rake_tasks'
2
- Alula::RakeTasks.install_tasks