adva-static 0.0.9 → 0.0.11

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 (35) hide show
  1. data/lib/adva/static.rb +5 -2
  2. data/lib/adva/static/export.rb +1 -1
  3. data/lib/adva/static/export/store.rb +2 -2
  4. data/lib/adva/static/export/templates/config.ru +34 -10
  5. data/lib/adva/static/import.rb +13 -6
  6. data/lib/adva/static/import/format.rb +25 -29
  7. data/lib/adva/static/import/model.rb +9 -10
  8. data/lib/adva/static/import/model/base.rb +20 -43
  9. data/lib/adva/static/import/model/blog.rb +11 -17
  10. data/lib/adva/static/import/model/page.rb +1 -16
  11. data/lib/adva/static/import/model/post.rb +21 -48
  12. data/lib/adva/static/import/model/section.rb +17 -23
  13. data/lib/adva/static/import/model/site.rb +11 -35
  14. data/lib/adva/static/import/source.rb +17 -72
  15. data/lib/adva/static/import/source/base.rb +59 -0
  16. data/lib/adva/static/import/source/blog.rb +37 -0
  17. data/lib/adva/static/import/source/page.rb +17 -0
  18. data/lib/adva/static/import/source/path.rb +84 -0
  19. data/lib/adva/static/import/source/post.rb +67 -0
  20. data/lib/adva/static/import/source/section.rb +39 -0
  21. data/lib/adva/static/import/source/site.rb +44 -0
  22. data/lib/adva/static/server.rb +38 -0
  23. data/lib/adva/static/{rack → server}/export.rb +1 -1
  24. data/lib/adva/static/{rack → server}/request.rb +1 -1
  25. data/lib/adva/static/{rack → server}/static.rb +2 -2
  26. data/lib/adva/static/{rack → server}/watch.rb +4 -4
  27. data/lib/adva/static/server/watch/handler.rb +57 -0
  28. data/lib/adva/tasks/static.rb +3 -4
  29. data/lib/adva_static/version.rb +1 -1
  30. data/lib/testing/step_definitions.rb +3 -0
  31. data/lib/testing/test_helper.rb +36 -31
  32. metadata +145 -104
  33. data/lib/adva/static/rack.rb +0 -15
  34. data/lib/adva/static/watch.rb +0 -7
  35. data/lib/adva/static/watch/handler.rb +0 -57
@@ -1,12 +1,15 @@
1
1
  require 'adva/core'
2
+ require 'adva/blog'
3
+ require 'adva/cache'
4
+ require 'adva/categories'
5
+ require 'adva/markup'
2
6
 
3
7
  module Adva
4
8
  class Static < ::Rails::Engine
5
9
  autoload :Export, 'adva/static/export'
6
10
  autoload :Import, 'adva/static/import'
7
- autoload :Watch, 'adva/static/watch'
8
- autoload :Rack, 'adva/static/rack'
9
11
  autoload :Setup, 'adva/static/setup'
12
+ autoload :Server, 'adva/static/server'
10
13
 
11
14
  include Adva::Engine
12
15
  end
@@ -28,7 +28,7 @@ module Adva
28
28
  roots = config[:roots] || %w(/)
29
29
  queue.push(*roots.map { |path| Path.new(path) })
30
30
 
31
- FileUtils.rm_r(Dir[target.join('*')])
31
+ FileUtils.rm_r(Dir[target.join('*')] - [target.join('config.ru').to_s])
32
32
  end
33
33
 
34
34
  def run
@@ -20,11 +20,11 @@ module Adva
20
20
  FileUtils.mkdir_p(File.dirname(path))
21
21
  File.open(path, 'w+') { |f| f.write(body) }
22
22
  end
23
-
23
+
24
24
  def purge(path)
25
25
  dir.join(path.filename).delete rescue Errno::ENOENT
26
26
  end
27
27
  end
28
28
  end
29
29
  end
30
- end
30
+ end
@@ -1,14 +1,38 @@
1
- Dir.chdir('..') until File.exists?('config/environment.rb')
1
+ # This config.ru file simply serves static files in the format exported by
2
+ # adva-static. I.e. you can use it (e.g.) to deploy exported html files to
3
+ # Heroku.
2
4
 
3
- require 'config/environment.rb'
5
+ class Static < ::Rack::File
6
+ attr_reader :app, :root
4
7
 
5
- Rails::Application.configure do
6
- ActionController::Base.allow_forgery_protection = false
7
- end
8
+ def initialize(app, root)
9
+ @app = app
10
+ @root = root
11
+ end
12
+
13
+ def call(env)
14
+ if get?(env) && path = static(env)
15
+ super(env.merge('PATH_INFO' => path))
16
+ else
17
+ app.call(env)
18
+ end
19
+ end
20
+
21
+ protected
8
22
 
9
- use Adva::Static::Rack::Watch
10
- use Adva::Static::Rack::Export
11
- use Adva::Static::Rack::Static, ::File.expand_path('../export', __FILE__)
23
+ def static(env)
24
+ path = env['PATH_INFO'].chomp('/')
25
+ [path, "#{path}.html", "#{path}/index.html"].detect { |path| file?(path) }
26
+ end
27
+
28
+ def file?(path)
29
+ File.file?(File.join(root, ::Rack::Utils.unescape(path)))
30
+ end
31
+
32
+ def get?(env)
33
+ env['REQUEST_METHOD'] == 'GET'
34
+ end
35
+ end
12
36
 
13
- puts 'listening.'
14
- run Rails.application
37
+ use Static, ::File.expand_path('..', __FILE__)
38
+ run lambda { [404, { 'content-type' => 'text/html' }, '<h1>404 Not found.</h1>'] }
@@ -9,22 +9,23 @@ module Adva
9
9
  attr_reader :root
10
10
 
11
11
  def initialize(options = {})
12
- @root = Pathname.new(File.expand_path(options[:source] || 'import'))
12
+ @root = Source::Path.new(File.expand_path(options[:source] || 'import'))
13
13
  end
14
14
 
15
15
  def run
16
16
  Adva.out.puts "importing from #{root}"
17
17
  Account.all.each(&:destroy)
18
- Model::Site.new(root).updated_record.save!
18
+ Category.delete_all
19
+ Model::Site.new(root).update!
19
20
  end
20
21
 
21
22
  def import(path)
22
- model = recognize(path).first
23
- model.updated_record.save! if model
23
+ model = recognize(path)
24
+ model.update! if model
24
25
  end
25
26
 
26
27
  def request_for(path)
27
- model = recognize(path).first
28
+ model = recognize(path)
28
29
  Request.new(model.source, model.record, model.attributes)
29
30
  end
30
31
 
@@ -35,7 +36,13 @@ module Adva
35
36
  end
36
37
 
37
38
  def recognize(path)
38
- Model.recognize([source(path)])
39
+ Model.build(Source.recognize([normalize_path(path)]).first)
40
+ end
41
+
42
+ def normalize_path(path)
43
+ path.gsub!(root.to_s, '')
44
+ path.gsub!(/^\//, '')
45
+ root.join(path)
39
46
  end
40
47
  end
41
48
  end
@@ -1,3 +1,5 @@
1
+ require 'hashr'
2
+
1
3
  module Adva
2
4
  class Static
3
5
  class Import
@@ -14,42 +16,36 @@ module Adva
14
16
  @path = path
15
17
  end
16
18
 
17
- def load(target)
18
- data.each do |name, value|
19
- define_attribute(target, name) if define_attribute?(target, name)
20
- target.instance_variable_set(:"@#{name}", value)
21
- end if data.is_a?(Hash)
22
- end
23
-
24
- def define_attribute?(target, name)
25
- !target.attribute_name?(name) && target.column_name?(name)
26
- end
27
-
28
- def define_attribute(target, name)
29
- target.attribute_names << name
30
- target.attribute_names.uniq!
31
- target.class.send(:attr_reader, name) unless target.respond_to?(name)
32
- end
19
+ # def load(target)
20
+ # data.each do |name, value|
21
+ # define_attribute(target, name) # if define_attribute?(target, name)
22
+ # target.instance_variable_set(:"@#{name}", value)
23
+ # end if data.is_a?(Hash)
24
+ # end
25
+
26
+ # def define_attribute?(target, name)
27
+ # !target.attribute_name?(name) && target.column_name?(name)
28
+ # end
29
+
30
+ # def define_attribute(target, name)
31
+ # # target.attribute_names << name
32
+ # target.attribute_names.uniq!
33
+ # target.class.send(:attr_reader, name) unless target.respond_to?(name)
34
+ # end
33
35
  end
34
36
 
35
37
  class Yml < Base
36
- def data
37
- @data ||= YAML.load_file(path)
38
+ def read
39
+ YAML.load_file(path)
38
40
  end
39
41
  end
40
42
 
41
43
  class Jekyll < Base
42
- def data
43
- @data ||= begin
44
- file =~ /^(---\s*\n.*?\n?)^---\s*$\n?(.*)/m
45
- data = YAML.load($1) rescue {}
46
- data.merge!(:body => $2) if $2
47
- data
48
- end
49
- end
50
-
51
- def file
52
- @file ||= File.read(path)
44
+ def read
45
+ File.read(path) =~ /^(---\s*\n.*?\n?)^---\s*$\n?(.*)/m
46
+ data = YAML.load($1) rescue {}
47
+ data.merge!(:body => $2) if $2
48
+ data
53
49
  end
54
50
  end
55
51
  end
@@ -2,20 +2,19 @@ module Adva
2
2
  class Static
3
3
  class Import
4
4
  module Model
5
- autoload :Base, 'adva/static/import/model/base'
6
- autoload :Blog, 'adva/static/import/model/blog'
7
- autoload :Page, 'adva/static/import/model/page'
8
- autoload :Post, 'adva/static/import/model/post'
9
- autoload :Section, 'adva/static/import/model/section'
10
- autoload :Site, 'adva/static/import/model/site'
5
+ autoload :Base, 'adva/static/import/model/base'
6
+ autoload :Blog, 'adva/static/import/model/blog'
7
+ autoload :Page, 'adva/static/import/model/page'
8
+ autoload :Post, 'adva/static/import/model/post'
9
+ autoload :Section, 'adva/static/import/model/section'
10
+ autoload :Site, 'adva/static/import/model/site'
11
11
 
12
12
  class << self
13
- def recognize(sources)
14
- types = [Site, Post, Section]
15
- types.map { |type| type.recognize(sources) }.flatten.compact.sort
13
+ def build(source, *args)
14
+ const_get(source.model_name).new(source, *args)
16
15
  end
17
16
  end
18
17
  end
19
18
  end
20
19
  end
21
- end
20
+ end
@@ -8,69 +8,46 @@ module Adva
8
8
  attr_reader :source, :attribute_names
9
9
 
10
10
  def initialize(source)
11
- @source = source
12
- load
11
+ @source = source.is_a?(Source::Base) ? source : Source.build(model_name, source)
13
12
  end
14
13
 
15
- def attributes
16
- attributes = attribute_names.map { |name| [name, self.send(name)] unless self.send(name).nil? }
17
- attributes = Hash[*attributes.compact.flatten_once]
18
- record && record.id ? attributes.merge(:id => record.id.to_s) : attributes
19
- end
20
-
21
- def attribute_name?(name)
22
- attribute_names.include?(name.to_sym)
23
- end
24
-
25
- def column_name?(name)
26
- model.column_names.include?(name.to_s)
14
+ def update!
15
+ updated_record.save!
27
16
  end
28
17
 
29
18
  def updated_record
30
19
  record.tap { |record| record.attributes = attributes }
31
20
  end
32
21
 
33
- def model
34
- self.class.name.demodulize.constantize
35
- end
36
-
37
- def site_id
38
- site.id.to_s
39
- end
40
-
41
- def slug
42
- source.basename
43
- end
44
-
45
- def path
46
- source.path
22
+ def attributes
23
+ attributes = attribute_names.map { |name| [name, attribute_value(name)] if attribute_value(name) } # attribute?(name)
24
+ attributes = Hashr.new(Hash[*attributes.compact.flatten_once])
25
+ record && record.id ? attributes.merge(:id => record.id.to_s) : attributes
47
26
  end
48
27
 
49
- def body
50
- @body || ''
28
+ def attribute_names
29
+ source.data.keys
51
30
  end
52
31
 
53
- def updated_at
54
- source.mtime
32
+ def attribute_value(name)
33
+ respond_to?(name) ? self.send(name) : source.data.send(name)
55
34
  end
56
35
 
57
- def loadable
58
- @loadable ||= source.full_path
36
+ def attribute?(name)
37
+ source.data.key?(name) || respond_to?(name)
59
38
  end
60
39
 
61
- def load
62
- if loadable.exist?
63
- format = Format.for(loadable) and format.load(self)
64
- end
40
+ def model
41
+ model_name.constantize
65
42
  end
66
43
 
67
- def ==(other)
68
- source == other
44
+ def model_name
45
+ @model_name ||= self.class.name.demodulize
69
46
  end
70
47
 
71
- def <=>(other)
72
- source <=> other.source
73
- end
48
+ # def updated_at
49
+ # source.mtime
50
+ # end
74
51
  end
75
52
  end
76
53
  end
@@ -3,28 +3,22 @@ module Adva
3
3
  class Import
4
4
  module Model
5
5
  class Blog < Section
6
- class << self
7
- def recognize(sources)
8
- return [] if sources.blank?
9
-
10
- sources = Array(sources)
11
- posts = sources.select { |source| Post.permalink?(source) }
12
- posts = sources.map(&:directory).map(&:files).flatten.select { |s| Post.permalink?(s) } if posts.blank?
13
-
14
- blogs = posts.map { |post| Post.new(post).section_source }.flatten.uniq
15
- blogs = blogs.map { |blog| sources.detect { |source| blog.path == source.path } || blog }
16
-
17
- sources.replace(sources - blogs - posts.map(&:self_and_parents).flatten)
18
- blogs.map { |source| new(source) }
19
- end
6
+ def update!
7
+ super
8
+ categories.each { |category| category.save! }
9
+ posts.each { |post| post.update! }
20
10
  end
21
11
 
22
12
  def attribute_names
23
- @attribute_names ||= super + [:posts_attributes]
13
+ @attribute_names ||= super - [:categories, :posts]
14
+ end
15
+
16
+ def categories
17
+ @categories ||= source.categories.map { |category| Category.new(:name => category, :section => record) }
24
18
  end
25
19
 
26
- def posts_attributes
27
- Post.recognize(source.files).map(&:attributes)
20
+ def posts
21
+ @posts ||= source.posts.map { |post| Post.new(post, self) }
28
22
  end
29
23
  end
30
24
  end
@@ -3,23 +3,8 @@ module Adva
3
3
  class Import
4
4
  module Model
5
5
  class Page < Section
6
- PATTERN = %r([\w-]+\.(#{Source::TYPES.join('|')})$)
7
-
8
- class << self
9
- def recognize(sources)
10
- return [] if sources.blank?
11
-
12
- pages = sources.select { |source| source.to_s =~ PATTERN }
13
- sources.replace(sources - pages)
14
-
15
- pages = pages.map { |source| source.self_and_parents.map(&:find_or_self) }.flatten.uniq
16
- pages = pages.map { |source| new(source) }
17
- pages
18
- end
19
- end
20
-
21
6
  def attribute_names
22
- @attribute_names ||= super + [:body]
7
+ @attribute_names ||= super | [:body]
23
8
  end
24
9
  end
25
10
  end
@@ -3,73 +3,46 @@ module Adva
3
3
  class Import
4
4
  module Model
5
5
  class Post < Base
6
- PERMALINK = %r((?:^|/)(\d{4})(?:\-|\/)(\d{1,2})(?:\-|\/)(\d{1,2})(?:\-|\/)(.*)$)
6
+ delegate :permalink, :published_at, :to => :source
7
7
 
8
- class << self
9
- def recognize(sources)
10
- posts = sources.select { |source| source.path =~ PERMALINK }
11
- sources.replace(sources - posts.map(&:self_and_parents).flatten)
12
- posts.map { |post| new(post) }
13
- end
8
+ attr_reader :section
14
9
 
15
- def permalink?(path)
16
- path.to_s =~ PERMALINK
17
- end
18
-
19
- def strip_permalink(source)
20
- Source.new(source.to_s.gsub(Post::PERMALINK, ''), source.root)
21
- end
10
+ def initialize(source, section = nil)
11
+ super(source)
12
+ @section = section
22
13
  end
23
14
 
24
- def attribute_names
25
- @attribute_names ||= [:site_id, :section_id, :title, :body, :published_at]
15
+ def update!
16
+ super
17
+ record.update_attributes!(:categories => categories)
26
18
  end
27
19
 
28
20
  def record
29
- @record ||= section.posts.by_permalink(*permalink).all.first || section.posts.build
30
- end
31
-
32
- def site_id
33
- section.site_id.to_s
34
- end
35
-
36
- def section
37
- @section ||= Blog.new(section_source).record
21
+ @record ||= ::Post.by_permalink(*permalink).first || ::Post.new
38
22
  end
39
23
 
40
- def section_id
41
- section.id.to_s
42
- end
43
-
44
- def section_source
45
- @section_source ||= begin
46
- source = self.class.strip_permalink(self.source)
47
- if source.path.present?
48
- source.find_or_self
49
- else
50
- Source.new(source.join('index'), source.root).find_or_self
51
- end
52
- end
24
+ def attribute_names
25
+ @attribute_names ||= (super | [:site_id, :section_id, :title, :body, :slug, :published_at, :filter]) - [:categories]
53
26
  end
54
27
 
55
- def slug
56
- @slug ||= SimpleSlugs::Slug.new(title).to_s
28
+ def site
29
+ section.try(:site)
57
30
  end
58
31
 
59
- def title
60
- @title ||= path_tokens.last.titleize
32
+ def site_id
33
+ site ? site.record.id.to_s : nil
61
34
  end
62
35
 
63
- def permalink
64
- @permalink ||= path_tokens.to_a[0..-2] << slug
36
+ def section
37
+ @section ||= Section.new(source.strip_permalink)
65
38
  end
66
39
 
67
- def path_tokens
68
- @path_tokens ||= source.to_s.gsub(/\.\w+$/, '').match(PERMALINK).to_a[1..-1]
40
+ def section_id
41
+ section ? section.record.id.to_s : nil
69
42
  end
70
43
 
71
- def published_at
72
- @published_at ||= DateTime.civil(*permalink[0..-2].map(&:to_i))
44
+ def categories
45
+ @categories ||= source.data.categories.map { |name| Category.find_or_create_by_name(name, :section_id => section.record.id) }
73
46
  end
74
47
  end
75
48
  end