maglove 0.8.1 → 1.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +157 -0
  4. data/Gemfile.lock +59 -49
  5. data/bin/maglove +13 -13
  6. data/data/maglove/export.haml +11 -0
  7. data/data/maglove/index.haml +17 -0
  8. data/data/maglove/maglove.css +62 -0
  9. data/data/maglove/maglove.haml +18 -0
  10. data/data/maglove/maglove.js +68 -0
  11. data/lib/block_resolver.rb +6 -0
  12. data/lib/ext/thor/option.rb +43 -0
  13. data/lib/magloft/api.rb +39 -0
  14. data/lib/magloft/api_caller.rb +67 -0
  15. data/lib/magloft/remote_collection.rb +50 -0
  16. data/lib/magloft/remote_resource.rb +124 -0
  17. data/lib/magloft/transformable.rb +11 -0
  18. data/lib/magloft/typeloft_block.rb +18 -0
  19. data/lib/magloft/typeloft_image.rb +18 -0
  20. data/lib/magloft/typeloft_template.rb +18 -0
  21. data/lib/magloft/typeloft_theme.rb +41 -0
  22. data/lib/magloft.rb +3 -0
  23. data/lib/maglove/application.rb +10 -12
  24. data/lib/maglove/asset/theme.rb +37 -32
  25. data/lib/maglove/commands/assets.rb +85 -0
  26. data/lib/maglove/commands/base.rb +55 -0
  27. data/lib/maglove/commands/fonts.rb +69 -0
  28. data/lib/maglove/commands/main.rb +24 -0
  29. data/lib/maglove/commands/theme.rb +197 -0
  30. data/lib/maglove/helper/log_helper.rb +3 -18
  31. data/lib/maglove/middleware/live_reload.rb +97 -0
  32. data/lib/maglove/phantom_script.rb +9 -10
  33. data/lib/maglove/server.rb +46 -78
  34. data/lib/maglove/tilt/coffee_template.rb +7 -6
  35. data/lib/maglove/tilt/haml_template.rb +4 -4
  36. data/lib/maglove/tilt/js_template.rb +8 -8
  37. data/lib/maglove/tilt/less_template.rb +5 -4
  38. data/lib/maglove/tilt/scss_template.rb +17 -11
  39. data/lib/maglove/tilt/yaml_template.rb +3 -2
  40. data/lib/maglove/version.rb +1 -1
  41. data/lib/maglove/workspace.rb +41 -0
  42. data/lib/maglove.rb +38 -49
  43. data/lib/powersnap.rb +24 -0
  44. data/lib/workspace/workspace_dir/archive.rb +18 -0
  45. data/lib/workspace/workspace_dir.rb +98 -0
  46. data/lib/workspace/workspace_file/archive.rb +45 -0
  47. data/lib/workspace/workspace_file/media.rb +19 -0
  48. data/lib/workspace/workspace_file/net.rb +18 -0
  49. data/lib/workspace/workspace_file/parse.rb +21 -0
  50. data/lib/workspace/workspace_file.rb +99 -0
  51. data/lib/workspace.rb +11 -0
  52. data/maglove.gemspec +12 -12
  53. metadata +100 -86
  54. data/data/maglove/dump.haml +0 -58
  55. data/data/maglove/sdk.haml +0 -27
  56. data/lib/ext/commander/command.rb +0 -32
  57. data/lib/ext/commander/methods.rb +0 -8
  58. data/lib/maglove/asset/base_theme.rb +0 -17
  59. data/lib/maglove/command/compile.rb +0 -44
  60. data/lib/maglove/command/compress.rb +0 -28
  61. data/lib/maglove/command/copy.rb +0 -35
  62. data/lib/maglove/command/core.rb +0 -23
  63. data/lib/maglove/command/font.rb +0 -80
  64. data/lib/maglove/command/server.rb +0 -16
  65. data/lib/maglove/command/sync.rb +0 -17
  66. data/lib/maglove/command/theme.rb +0 -175
  67. data/lib/maglove/command/util.rb +0 -45
  68. data/lib/maglove/helper/asset_helper.rb +0 -24
  69. data/lib/maglove/helper/command_helper.rb +0 -67
  70. data/lib/maglove/helper/theme_helper.rb +0 -105
  71. data/lib/maglove/server/hpub.rb +0 -185
  72. data/lib/maglove/template/tumblr.rb +0 -81
  73. data/lib/maglove/tilt/twig_template.rb +0 -49
@@ -1,185 +0,0 @@
1
- module MagLove
2
- class Server
3
- module Hpub
4
-
5
- class IssueServlet < WEBrick::HTTPServlet::AbstractServlet
6
- include Commander::Methods
7
-
8
- def do_GET(req, res)
9
- theme = File.basename(req.path, ".*")
10
- config = theme_config(nil, theme)
11
- working_dir = Dir.mktmpdir
12
- data_dir = Gem.datadir("maglove")
13
-
14
- # Create book.json
15
- book_json = {
16
- "hpub" => 1,
17
- "title" => config["name"],
18
- "author" => ["MagLove"],
19
- "creator" => ["MagLove"],
20
- "date" => Time.now.strftime("%Y-%m-%d %H:%M:%S UTC"),
21
- "url" => "book://www.magloft.com",
22
- "orientation" => "both",
23
- "-baker-background" => "#FFFFFF",
24
- "-baker-index-height" => 240,
25
- "-baker-media-autoplay" => false,
26
- "-baker-rendering" => "three-cards",
27
- "-baker-page-numbers-color" => "#333",
28
- "-baker-vertical-bounce" => true,
29
- "-baker-page-turn-tap" => true,
30
- "-baker-start-at-page" => 1,
31
- "-baker-max-zoom-level" => 2.0,
32
- "zoomable" => true,
33
- "contents" => config["templates"].map{|t| "#{t}.html"}
34
- }
35
- File.open("#{working_dir}/book.json", "w"){|f| f.write(book_json.to_json) }
36
-
37
- # Copy assets
38
- FileUtils.cp_r("dist/fonts", "#{working_dir}/fonts")
39
- FileUtils.cp_r("dist/themes/#{theme}/thumbs", "#{working_dir}/thumbs")
40
- FileUtils.cp("dist/themes/#{theme}/thumbs/#{config["templates"][0]}.png", "#{working_dir}/cover.png")
41
- FileUtils.mkdir_p("#{working_dir}/stylesheets")
42
- FileUtils.cp("#{data_dir}/hpub/index.css", "#{working_dir}/stylesheets/index.css")
43
- FileUtils.mkdir_p("#{working_dir}/themes")
44
- FileUtils.cp_r("dist/themes/#{theme}", "#{working_dir}/themes/#{theme}")
45
-
46
- # Create index html
47
- index_contents = File.read("#{data_dir}/hpub/index.haml")
48
- engine = Haml::Engine.new(index_contents)
49
- index_html = engine.render(Object.new, config)
50
- File.open("#{working_dir}/index.html", "w"){|f| f.write(index_html) }
51
-
52
- # Compile themes
53
- Hamloft::Options.defaults[:asset_uri] = "."
54
- theme_glob("templates/*.{html,haml,twig}", theme).each do |file|
55
- # compile template
56
- template = File.basename(file, ".*")
57
- locals = {}
58
- locals_contents = theme_contents(file.sub(/\.[^.]+\z/, ".yml"), theme)
59
- if locals_contents
60
- locals = YAML.load(locals_contents).with_indifferent_access
61
- end
62
- asset = theme_asset(file, theme, locals)
63
-
64
- # wrap in page
65
- page_contents = File.read("#{data_dir}/hpub/page.haml")
66
- engine = Haml::Engine.new(page_contents)
67
- page_html = engine.render(Object.new, {template: template, theme: theme, contents: compile_html(asset.contents)})
68
-
69
- # Write to file
70
- File.open("#{working_dir}/#{template}.html", "w"){|f| f.write(page_html) }
71
- end
72
-
73
- # Delete zip file
74
- zip_path = "#{working_dir}/themes/#{theme}/#{theme}.tar.gz"
75
- FileUtils.rm_f(zip_path) if File.exists?(zip_path)
76
-
77
- # Create zip archive
78
- FileUtils.rm_f("dist/#{theme}.hpub") if File.exists?("dist/#{theme}.hpub")
79
- Zip::File.open("dist/#{theme}.hpub", Zip::File::CREATE) do |zipfile|
80
- Dir[File.join(working_dir, '**', '**')].each do |file|
81
- zipfile.add(file.sub("#{working_dir}/", ''), file)
82
- end
83
- end
84
-
85
- # respond
86
- res.status = 200
87
- res['Content-Type'] = "application/zip"
88
- res.body = File.read("dist/#{theme}.hpub")
89
- end
90
-
91
- private
92
-
93
- def compile_html(contents)
94
- doc = Nokogiri::HTML.fragment(contents.force_encoding("UTF-8"))
95
-
96
- # unwrap widgets
97
- doc.css("._typeloft_widget").each do |node|
98
-
99
- # remove unneeded attributes
100
- node.attributes.each do |key, attribute|
101
- node.attributes[key].remove if key != "style" and key != "class"
102
- end
103
-
104
- # clean up classes
105
- if not node.attributes["class"].nil?
106
- classList = node.attributes["class"].value.split(" ")
107
- classList.reject!{|cls| ["_typeloft_widget", "ui-resizable", "_typeloft_widget_selected", "_typeloft_widget_hover"].include?(cls)}
108
- node.attributes["class"].value = classList.join(" ")
109
- end
110
- end
111
-
112
- # remove scripts
113
- doc.css('script').remove()
114
-
115
- # unwrap drop containers
116
- doc.css("._typeloft_widget_drop_container").each do |node|
117
- node.children.each do |child|
118
- node.parent << child
119
- end
120
- node.remove
121
- end
122
-
123
- # remove data-typeloft-slug attributes
124
- doc.xpath( './/*[@data-typeloft-slug]|*[@data-typeloft-slug]' ).each do |node|
125
- node.attributes["data-typeloft-slug"].remove
126
- end
127
-
128
- # remove contenteditable attributes
129
- doc.xpath( './/*[@contenteditable]|*[@contenteditable]' ).each do |node|
130
- node.attributes["contenteditable"].remove
131
- end
132
-
133
- # remove widget containers
134
- doc.css("._typeloft_widget_container").remove()
135
-
136
- # remove typeloft classes
137
- doc.xpath(".//*[@*[contains(., '_typeloft_')]]").each do |node|
138
- classes = node[:class].split(' ').select{|cls| !cls.include?('_typeloft_')}
139
- node[:class] = classes.join(' ')
140
- end
141
-
142
- # convert iframe https links to http
143
- doc.search('iframe[src*="https://"]').each do |node|
144
- src = node[:src].sub('https://', 'http://')
145
- node[:src] = src
146
- end
147
-
148
- # fetch html
149
- clean_html_chars(doc.to_s)
150
- end
151
-
152
- def clean_html_chars(characters)
153
- ["\u1680", "\u180E", "\u2000", "\u2001", "\u2002", "\u2003", "\u2004", "\u2005", "\u2006", "\u2007", "\u2008", "\u2009", "\u200A", "\u200B", "\u202F", "\u205F", "\u3000", "\uFEFF"].each do |char|
154
- characters = characters.force_encoding("UTF-8").gsub(char, "&nbsp&nbsp")
155
- end
156
- characters.force_encoding("BINARY").gsub(0xC2.chr+0xA0.chr+" ","&nbsp;&nbsp;").gsub(0xC2.chr+0xA0.chr,"&nbsp;")
157
- end
158
- end
159
-
160
- class ManifestServlet < WEBrick::HTTPServlet::AbstractServlet
161
- include Commander::Methods
162
-
163
- def do_GET(req, res)
164
- res.content_type = "application/json"
165
- manifest = []
166
- Dir.glob("dist/themes/*") do |dir|
167
- theme = File.basename(dir)
168
- config = theme_config(nil, theme)
169
- manifest.push({
170
- name: theme,
171
- title: config["name"],
172
- product_id: nil,
173
- info: config["description"],
174
- date: Time.now.strftime("%Y-%m-%d %H:%M:%S"),
175
- url: "http://#{req.host}:#{req.port}/issue/#{theme}.hpub",
176
- cover: "http://#{req.host}:#{req.port}/themes/#{theme}/thumbs/#{config["templates"][0]}.png"
177
- })
178
- end
179
- res.body = manifest.to_json
180
- end
181
- end
182
-
183
- end
184
- end
185
- end
@@ -1,81 +0,0 @@
1
- module MagLove
2
- module Template
3
- class Tumblr < Hamloft::Template
4
-
5
- def chunks
6
- self.doc.children
7
- end
8
-
9
- def container(&block)
10
- haml.container_widget(padding_left: "0em", padding_right: "0em", &block)
11
- end
12
-
13
- def process_chunk(chunk)
14
- case chunk.name
15
- when "text"
16
- haml.paragraph_widget({margin_left: "2em", margin_right: "2em"}, chunk.text)
17
- when "p"
18
- haml.paragraph_widget({margin_left: "2em", margin_right: "2em"}, chunk.text)
19
- when "ol", "ul"
20
- haml.paragraph_widget({margin_left: "2em", margin_right: "2em"}) do
21
- haml.haml_tag chunk.name, class: "user-list" do
22
- chunk.children.each do |child|
23
- haml.haml_tag :li do
24
- haml.haml_concat child.text
25
- end
26
- end
27
- end
28
- end
29
- when "h1", "h2", "h3", "h4", "h5"
30
- haml.heading_widget({type: chunk.name, margin_left: "2em", margin_right: "2em", margin_bottom: "1em"}, chunk.text)
31
- when "a"
32
- if chunk.css("img").length > 0
33
- haml.image_widget_link(href: chunk.attribute("href").to_s, source: chunk.css("img").first.attribute("src").to_s)
34
- else
35
- haml.paragraph_widget({margin_left: "2em", margin_right: "2em"}, chunk.text) do
36
- haml.link(chunk.attribute("href").to_s)
37
- end
38
- end
39
- when "figure"
40
- case chunk.children.first.name
41
- when "img"
42
- haml.image_widget(source: chunk.children.first.attribute("src").to_s, margin_bottom: "1em")
43
- when "iframe"
44
- iframe_url = chunk.children.first.attribute("src").value
45
- if iframe_url.include?("screen.yahoo.com") and match = iframe_url.match("screen\.yahoo\.com\/([a-z0-9\-]+)\.html")
46
- haml.yahoo_screen_widget(yahoo_screen_id: match[1], margin_bottom: "1em")
47
- elsif iframe_url.include?("www.youtube.com") and match = iframe_url.match("www\.youtube\.com\/.*\/([a-zA-Z0-9]+)")
48
- haml.youtube_widget(youtube_id: match[1], margin_bottom: "1em")
49
- else
50
- puts "-- unhandled iframe: #{iframe_url}"
51
- end
52
- else
53
- puts "-- unhandled figure: #{chunk.children.first.name}"
54
- end
55
- when "div"
56
- if chunk.attribute("class").to_s == "sponlogo"
57
- haml.container_widget background_color: "white", padding_left: "1em", padding_right: "1em", padding_bottom: "0.5em", padding_top: "1em" do
58
- haml.columns_widget columns: "3x9" do |row|
59
- haml.column row do
60
- process_chunk(chunk.children()[0])
61
- end
62
- haml.column row do
63
- haml.paragraph_widget({align: "right"}, chunk.children()[1].text)
64
- end
65
- end
66
- end
67
- else
68
- haml.container_widget do
69
- chunk.children.each do |child_chunk|
70
- process_chunk(child_chunk)
71
- end
72
- end
73
- end
74
- else
75
- puts "-- unhandled chunk: #{chunk.name}"
76
- end
77
- end
78
-
79
- end
80
- end
81
- end
@@ -1,49 +0,0 @@
1
- require 'tilt'
2
- require 'yaml'
3
-
4
- module MagLove
5
- module Tilt
6
- class TwigTemplate < ::Tilt::Template
7
- self.default_mime_type = 'theme/html'
8
-
9
- def initialize_engine
10
- install_php_dependencies
11
- end
12
-
13
- def prepare; end
14
-
15
- def evaluate(scope, locals, &block)
16
- return @output if not @output.nil?
17
- yaml_file = Tempfile.new(['context-', '.yml'])
18
- yaml_data = locals.merge(scope.is_a?(Hash) ? scope : {}).stringify_keys
19
- begin
20
- File.open(yaml_file.path, 'w'){|file| file.write(yaml_data.to_yaml)}
21
- @output = `php #{binary_path} render -d '#{File.dirname(file)}' -y '#{yaml_file.path}' '#{File.basename(file)}'`
22
- rescue
23
- raise
24
- ensure
25
- yaml_file.close
26
- yaml_file.unlink
27
- end
28
- end
29
-
30
- private
31
-
32
- def install_php_dependencies
33
- if !File.exists?(binary_path)
34
- require 'open-uri'
35
- File.open(binary_path, "wb") do |saved_file|
36
- open("https://github.com/MagLoft/twigster/raw/master/twigster.phar", "rb") do |read_file|
37
- saved_file.write(read_file.read)
38
- end
39
- end
40
- end
41
- end
42
-
43
- def binary_path
44
- File.join(Gem.datadir("maglove"), "twigster.phar")
45
- end
46
- end
47
-
48
- end
49
- end