maglove 0.8.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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