adva-static 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/adva-static.rb +1 -0
- data/lib/adva/static.rb +13 -0
- data/lib/adva/static/export.rb +104 -0
- data/lib/adva/static/export/page.rb +45 -0
- data/lib/adva/static/export/path.rb +49 -0
- data/lib/adva/static/export/queue.rb +27 -0
- data/lib/adva/static/export/store.rb +30 -0
- data/lib/adva/static/export/templates/config.ru +14 -0
- data/lib/adva/static/import.rb +42 -0
- data/lib/adva/static/import/format.rb +58 -0
- data/lib/adva/static/import/model.rb +21 -0
- data/lib/adva/static/import/model/base.rb +78 -0
- data/lib/adva/static/import/model/blog.rb +33 -0
- data/lib/adva/static/import/model/page.rb +28 -0
- data/lib/adva/static/import/model/post.rb +78 -0
- data/lib/adva/static/import/model/section.rb +51 -0
- data/lib/adva/static/import/model/site.rb +59 -0
- data/lib/adva/static/import/request.rb +92 -0
- data/lib/adva/static/import/source.rb +82 -0
- data/lib/adva/static/rack.rb +15 -0
- data/lib/adva/static/rack/export.rb +59 -0
- data/lib/adva/static/rack/request.rb +39 -0
- data/lib/adva/static/rack/static.rb +40 -0
- data/lib/adva/static/rack/watch.rb +88 -0
- data/lib/adva/static/setup.rb +68 -0
- data/lib/adva/static/watch.rb +7 -0
- data/lib/adva/static/watch/handler.rb +57 -0
- data/lib/adva/tasks/static.rb +73 -0
- data/lib/adva_static/version.rb +3 -0
- data/lib/testing/step_definitions.rb +85 -0
- data/lib/testing/test_helper.rb +133 -0
- metadata +35 -5
- data/lib/bundler/repository.rb +0 -118
@@ -0,0 +1,33 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
module Model
|
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
|
20
|
+
end
|
21
|
+
|
22
|
+
def attribute_names
|
23
|
+
@attribute_names ||= super + [:posts_attributes]
|
24
|
+
end
|
25
|
+
|
26
|
+
def posts_attributes
|
27
|
+
Post.recognize(source.files).map(&:attributes)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
module Model
|
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
|
+
def attribute_names
|
22
|
+
@attribute_names ||= super + [:body]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
module Model
|
5
|
+
class Post < Base
|
6
|
+
PERMALINK = %r((?:^|/)(\d{4})(?:\-|\/)(\d{1,2})(?:\-|\/)(\d{1,2})(?:\-|\/)(.*)$)
|
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
|
14
|
+
|
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
|
22
|
+
end
|
23
|
+
|
24
|
+
def attribute_names
|
25
|
+
@attribute_names ||= [:site_id, :section_id, :title, :body, :published_at]
|
26
|
+
end
|
27
|
+
|
28
|
+
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
|
38
|
+
end
|
39
|
+
|
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
|
53
|
+
end
|
54
|
+
|
55
|
+
def slug
|
56
|
+
@slug ||= SimpleSlugs::Slug.new(title).to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
def title
|
60
|
+
@title ||= path_tokens.last.titleize
|
61
|
+
end
|
62
|
+
|
63
|
+
def permalink
|
64
|
+
@permalink ||= path_tokens.to_a[0..-2] << slug
|
65
|
+
end
|
66
|
+
|
67
|
+
def path_tokens
|
68
|
+
@path_tokens ||= source.to_s.gsub(/\.\w+$/, '').match(PERMALINK).to_a[1..-1]
|
69
|
+
end
|
70
|
+
|
71
|
+
def published_at
|
72
|
+
@published_at ||= DateTime.civil(*permalink[0..-2].map(&:to_i))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
module Model
|
5
|
+
class Section < Base
|
6
|
+
class << self
|
7
|
+
def types
|
8
|
+
[Blog, Page]
|
9
|
+
end
|
10
|
+
|
11
|
+
def recognize(sources)
|
12
|
+
types.map { |type| type.recognize(sources) }.flatten.compact.sort
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def attribute_names
|
17
|
+
@attribute_names ||= [:site_id, :type, :name, :slug, :path]
|
18
|
+
end
|
19
|
+
|
20
|
+
def record
|
21
|
+
@record ||= site.send(model.name.underscore.pluralize).find_or_initialize_by_path(path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def site
|
25
|
+
@site ||= Site.new(source.root).record
|
26
|
+
end
|
27
|
+
|
28
|
+
def type
|
29
|
+
model.name
|
30
|
+
end
|
31
|
+
|
32
|
+
def name
|
33
|
+
@name ||= source.root? ? 'Home' : source.basename.titleize
|
34
|
+
end
|
35
|
+
|
36
|
+
def slug
|
37
|
+
@slug ||= source.root? ? SimpleSlugs::Slug.new(name) : super
|
38
|
+
end
|
39
|
+
|
40
|
+
def path
|
41
|
+
@path ||= source.root? ? slug : super
|
42
|
+
end
|
43
|
+
|
44
|
+
def loadable
|
45
|
+
@loadable ||= source.root? ? Source.new('index', source.root).find_or_self.full_path : source.full_path
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'site'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
class Import
|
6
|
+
module Model
|
7
|
+
class Site < Base
|
8
|
+
class << self
|
9
|
+
def recognize(sources)
|
10
|
+
sources.map { |source| new(sources.delete(source).root) if source.path == 'site' }.compact
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(root)
|
15
|
+
super(Source.new('', root))
|
16
|
+
end
|
17
|
+
|
18
|
+
def attribute_names
|
19
|
+
@attribute_names ||= [:account, :host, :name, :title, :sections_attributes]
|
20
|
+
end
|
21
|
+
|
22
|
+
def record
|
23
|
+
@record ||= model.find_or_initialize_by_host(host)
|
24
|
+
end
|
25
|
+
|
26
|
+
def host
|
27
|
+
@host ||= File.basename(source.root)
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
@name ||= host
|
32
|
+
end
|
33
|
+
|
34
|
+
def title
|
35
|
+
@title ||= name
|
36
|
+
end
|
37
|
+
|
38
|
+
def account
|
39
|
+
@account ||= ::Account.first || ::Account.new
|
40
|
+
end
|
41
|
+
|
42
|
+
def sections_attributes
|
43
|
+
sections.map(&:attributes)
|
44
|
+
end
|
45
|
+
|
46
|
+
def sections
|
47
|
+
@sections ||= Section.recognize(source.files).tap do |sections|
|
48
|
+
sections << Page.new(Source.new('index', source.root).find_or_self) if sections.empty?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def loadable
|
53
|
+
@loadable ||= Source.new('site', source.root).find_or_self.full_path
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
class Request
|
5
|
+
attr_reader :source, :record, :attributes
|
6
|
+
|
7
|
+
def initialize(source, record, attributes)
|
8
|
+
@source = source
|
9
|
+
@record = record
|
10
|
+
@attributes = attributes
|
11
|
+
end
|
12
|
+
|
13
|
+
def params
|
14
|
+
@params ||= begin
|
15
|
+
key = model_name.underscore.to_sym
|
16
|
+
if destroy?
|
17
|
+
params = { '_method' => 'delete', key => { :id => record.id } }
|
18
|
+
else
|
19
|
+
params = { model_name.underscore.to_sym => attributes }
|
20
|
+
params.merge!('_method' => 'put') if update?
|
21
|
+
end
|
22
|
+
stringify(params)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def path
|
27
|
+
controller.polymorphic_path(controller.resources)
|
28
|
+
end
|
29
|
+
|
30
|
+
def public_path
|
31
|
+
controller.public_url_for(controller.resources, :routing_type => :path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create?
|
35
|
+
!update? && !destroy?
|
36
|
+
end
|
37
|
+
|
38
|
+
def update?
|
39
|
+
record.persisted? && source.exist?
|
40
|
+
end
|
41
|
+
|
42
|
+
def destroy?
|
43
|
+
record.persisted? && !source.exist?
|
44
|
+
end
|
45
|
+
|
46
|
+
def controller
|
47
|
+
@controller ||= controller_name.constantize.new.tap do |controller|
|
48
|
+
controller.request = ActionDispatch::TestRequest.new
|
49
|
+
controller.params = params_for(controller)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def section_ids
|
56
|
+
@section_ids ||= Section.types.map { |type| :"#{type.underscore}_id" }
|
57
|
+
end
|
58
|
+
|
59
|
+
def model_name
|
60
|
+
record.class.name
|
61
|
+
end
|
62
|
+
|
63
|
+
def controller_name
|
64
|
+
"Admin::#{model_name.pluralize}Controller"
|
65
|
+
end
|
66
|
+
|
67
|
+
def params_for(controller)
|
68
|
+
names = controller.send(:symbols_for_association_chain).dup
|
69
|
+
names.map! { |name| :"#{name}_id" }
|
70
|
+
names << :id unless record.new_record?
|
71
|
+
|
72
|
+
names.inject(:action => record.new_record? ? :index : :show) do |params, name|
|
73
|
+
# umm. admin blog routes use :blog_id, but Post has a section_id
|
74
|
+
value = attributes[section_ids.include?(name) ? :section_id : name].to_s
|
75
|
+
params.merge(name => value)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def stringify(object)
|
80
|
+
case object
|
81
|
+
when Hash
|
82
|
+
object.each { |key, value| object[key] = stringify(value) }
|
83
|
+
when Array
|
84
|
+
object.map! { |element| stringify(element) }
|
85
|
+
else
|
86
|
+
object.to_s
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Adva
|
2
|
+
class Static
|
3
|
+
class Import
|
4
|
+
class Source < Pathname
|
5
|
+
TYPES = ['html', 'jekyll', 'yml']
|
6
|
+
EXTENSIONS = TYPES.map { |type| ".#{type}" }
|
7
|
+
|
8
|
+
attr_reader :root
|
9
|
+
|
10
|
+
delegate :exist?, :to => :full_path
|
11
|
+
|
12
|
+
def initialize(path, root = nil)
|
13
|
+
root ||= path.root if path.respond_to?(:root)
|
14
|
+
@root = Pathname.new(root.to_s)
|
15
|
+
|
16
|
+
path = path.to_s.gsub(root, '') if root
|
17
|
+
path = path.to_s[1..-1] if path.to_s[0, 1] == '/'
|
18
|
+
super(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def find_or_self
|
22
|
+
find or self
|
23
|
+
end
|
24
|
+
|
25
|
+
def find
|
26
|
+
file = Dir["#{root.join(path)}.{#{TYPES.join(',')}}"].first
|
27
|
+
Source.new(file, root) if file
|
28
|
+
end
|
29
|
+
|
30
|
+
def all
|
31
|
+
@all ||= Dir[root.join(path).join("**/*.{#{TYPES.join(',')}}")].map { |path| Source.new(path, root) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def files
|
35
|
+
files = path == 'index' ? directory.all : all
|
36
|
+
files.reject { |path| path.basename == 'site' }.sort
|
37
|
+
end
|
38
|
+
|
39
|
+
def root?
|
40
|
+
@_root ||= path == 'index' || full_path.to_s == root.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
def directory
|
44
|
+
@directory ||= self.class.new(dirname, root)
|
45
|
+
end
|
46
|
+
|
47
|
+
def basename
|
48
|
+
@basename ||= super.to_s.sub(/\.\w+$/, '')
|
49
|
+
end
|
50
|
+
|
51
|
+
def dirname
|
52
|
+
@dirname ||= super.to_s.sub(/^.$/, '')
|
53
|
+
end
|
54
|
+
|
55
|
+
def path
|
56
|
+
@_path ||= [dirname, basename].select(&:present?).join('/')
|
57
|
+
end
|
58
|
+
|
59
|
+
def full_path
|
60
|
+
@full_path ||= root.join(self)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self_and_parents
|
64
|
+
parents << self
|
65
|
+
end
|
66
|
+
|
67
|
+
def parents
|
68
|
+
@parents ||= begin
|
69
|
+
parts = self.to_s.split('/')[0..-2]
|
70
|
+
parts.inject([]) do |parents, part|
|
71
|
+
parents << Source.new(parts[0..parents.size].join('/'), root)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def <=>(other)
|
77
|
+
path == 'index' ? -1 : other.path == 'index' ? 1 : path <=> other.path
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'adva'
|
2
|
+
|
3
|
+
module Adva
|
4
|
+
class Static
|
5
|
+
module Rack
|
6
|
+
PURGE_HEADER = 'rack-cache.purge'
|
7
|
+
STORE_HEADER = 'rack-static.store'
|
8
|
+
|
9
|
+
autoload :Request, 'adva/static/rack/request'
|
10
|
+
autoload :Export, 'adva/static/rack/export'
|
11
|
+
autoload :Static, 'adva/static/rack/static'
|
12
|
+
autoload :Watch, 'adva/static/rack/watch'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|