adva-static 0.0.9 → 0.0.11

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