adva-static 0.0.3 → 0.0.4
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.
- 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
|