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
@@ -3,46 +3,40 @@ module Adva
3
3
  class Import
4
4
  module Model
5
5
  class Section < Base
6
- class << self
7
- def types
8
- [Blog, Page]
9
- end
6
+ attr_reader :parent
10
7
 
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]
8
+ def initialize(source, site = nil, parent = nil)
9
+ super(source)
10
+ @site = site
11
+ @parent = parent
18
12
  end
19
13
 
20
14
  def record
21
- @record ||= site.send(model.name.underscore.pluralize).find_or_initialize_by_path(path)
15
+ @record ||= model.find_or_initialize_by_slug(source.data.slug)
22
16
  end
23
17
 
24
- def site
25
- @site ||= Site.new(source.root).record
18
+ def attribute_names
19
+ @attribute_names ||= super | [:site_id, :parent_id, :type, :name, :slug]
26
20
  end
27
21
 
28
22
  def type
29
- model.name
23
+ model_name
30
24
  end
31
25
 
32
- def name
33
- @name ||= source.root? ? 'Home' : source.basename.titleize
26
+ def site
27
+ @site ||= Site.new(source.path.root)
34
28
  end
35
29
 
36
- def slug
37
- @slug ||= source.root? ? SimpleSlugs::Slug.new(name) : super
30
+ def site_id
31
+ site && site.record.persisted? ? site.record.id.to_s : nil
38
32
  end
39
33
 
40
- def path
41
- @path ||= source.root? ? slug : super
34
+ def parent
35
+ @parent ||= source.path.root? || source.path.parent.root? ? nil : Section.new(source.path.parent)
42
36
  end
43
37
 
44
- def loadable
45
- @loadable ||= source.root? ? Source.new('index', source.root).find_or_self.full_path : source.full_path
38
+ def parent_id
39
+ parent && parent.record.persisted? ? parent.record.id.to_s : nil
46
40
  end
47
41
  end
48
42
  end
@@ -3,53 +3,29 @@ module Adva
3
3
  class Import
4
4
  module Model
5
5
  class Site < Base
6
- class << self
7
- def recognize(sources)
8
- sources.map { |source| new(sources.delete(source).root) if source.path == 'site' }.compact
9
- end
10
- end
11
-
12
- def initialize(root)
13
- super(Source.new('', root))
14
- end
6
+ delegate :host, :to => :'source.data'
15
7
 
16
- def attribute_names
17
- @attribute_names ||= [:account, :host, :name, :title, :sections_attributes]
8
+ def update!
9
+ record.account = Account.first || Account.create
10
+ super
11
+ sections.each { |section| section.update! }
18
12
  end
19
13
 
20
14
  def record
21
15
  @record ||= model.find_or_initialize_by_host(host)
22
16
  end
23
17
 
24
- def host
25
- @host ||= File.basename(source.root)
26
- end
27
-
28
- def name
29
- @name ||= host
30
- end
31
-
32
- def title
33
- @title ||= name
34
- end
35
-
36
- def account
37
- @account ||= ::Account.first || ::Account.new
38
- end
39
-
40
- def sections_attributes
41
- sections.map(&:attributes)
18
+ def attribute_names
19
+ @attribute_names ||= (super | [:host, :name, :title]) - [:sections]
42
20
  end
43
21
 
44
22
  def sections
45
- @sections ||= Section.recognize(source.files).tap do |sections|
46
- sections << Page.new(Source.new('index', source.root).find_or_self) if sections.empty?
23
+ @sections ||= begin
24
+ sections = source.sections.map { |section| Model.build(section, self) }
25
+ sections << Page.new(source.path) if sections.empty?
26
+ sections
47
27
  end
48
28
  end
49
-
50
- def loadable
51
- @loadable ||= Source.new('site', source.root).find_or_self.full_path
52
- end
53
29
  end
54
30
  end
55
31
  end
@@ -1,80 +1,25 @@
1
1
  module Adva
2
2
  class Static
3
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
4
+ module Source
5
+ autoload :Base, 'adva/static/import/source/base'
6
+ autoload :Blog, 'adva/static/import/source/blog'
7
+ autoload :Path, 'adva/static/import/source/path'
8
+ autoload :Page, 'adva/static/import/source/page'
9
+ autoload :Post, 'adva/static/import/source/post'
10
+ autoload :Section, 'adva/static/import/source/section'
11
+ autoload :Site, 'adva/static/import/source/site'
12
+
13
+ TYPES = [Site] + Section::TYPES
14
+
15
+ class << self
16
+ def build(type, path)
17
+ const_get(type).new(path)
73
18
  end
74
- end
75
19
 
76
- def <=>(other)
77
- path == 'index' ? -1 : other.path == 'index' ? 1 : path <=> other.path
20
+ def recognize(paths)
21
+ [Site, Post, Section].map { |type| type.recognize(paths) }.flatten.compact.sort
22
+ end
78
23
  end
79
24
  end
80
25
  end
@@ -0,0 +1,59 @@
1
+ require 'hashr'
2
+
3
+ module Adva
4
+ class Static
5
+ class Import
6
+ module Source
7
+ class Base
8
+ delegate :exist?, :to => :path
9
+
10
+ attr_reader :path
11
+
12
+ def initialize(path)
13
+ @path = normalize_path(path)
14
+ end
15
+
16
+ def to_hash
17
+ data
18
+ end
19
+
20
+ def data
21
+ @data ||= Hashr.new(read || {})
22
+ end
23
+
24
+ def model_name
25
+ @model_name ||= self.class.name.demodulize
26
+ end
27
+
28
+ def <=>(other)
29
+ path <=> other.path
30
+ end
31
+
32
+ protected
33
+
34
+ def normalize_path(path)
35
+ path = path.is_a?(Path) ? path : Path.new(path)
36
+ path = path.parent if path.filename == 'index'
37
+ path
38
+ end
39
+
40
+ def loadable
41
+ raise "path #{path.inspect} is not a file" unless path.file?
42
+ path
43
+ end
44
+
45
+ def read
46
+ @read ||= begin
47
+ format = Format.for(loadable) if loadable.exist?
48
+ data = format.read if format
49
+ Hashr.new(data || {})
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+
59
+
@@ -0,0 +1,37 @@
1
+ module Adva
2
+ class Static
3
+ class Import
4
+ module Source
5
+ class Blog < Section
6
+ class << self
7
+ def recognize(paths)
8
+ posts = Post.recognize(paths)
9
+ blogs = posts.map { |post| post.strip_permalink }.flatten.uniq
10
+ blogs = blogs.map { |blog| paths.detect { |path| blog.to_s == path.to_s } || blog }
11
+
12
+ paths.replace(paths - blogs)
13
+ blogs.map { |path| new(path, posts) }
14
+ end
15
+ end
16
+
17
+ attr_reader :posts
18
+
19
+ def initialize(path, posts = [])
20
+ @posts = posts
21
+ super(path)
22
+ end
23
+
24
+ def categories
25
+ @categories ||= posts.map { |post| post.categories }.flatten.uniq.sort
26
+ end
27
+
28
+ def data
29
+ super.merge(:posts => posts, :categories => categories)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+
@@ -0,0 +1,17 @@
1
+ module Adva
2
+ class Static
3
+ class Import
4
+ module Source
5
+ class Page < Section
6
+ class << self
7
+ def recognize(paths)
8
+ paths.map { |path| new(path) }
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+
@@ -0,0 +1,84 @@
1
+ module Adva
2
+ class Static
3
+ class Import
4
+ module Source
5
+ class Path < Pathname
6
+ TYPES = ['html', 'jekyll', 'yml']
7
+ EXTENSIONS = TYPES.map { |type| ".#{type}" }
8
+
9
+ attr_reader :root
10
+
11
+ def initialize(path, root = nil)
12
+ super(path)
13
+ @root = self.class.new(root.to_s) if root && to_s != root.to_s
14
+ end
15
+
16
+ def root?
17
+ !@root || filename == 'index' && parent.root? || @root.to_s == to_s # i.e. this is the root path if no root is set
18
+ end
19
+
20
+ def root
21
+ root? ? self : @root
22
+ end
23
+
24
+ def parent
25
+ self.class.new(super, @root || self)
26
+ end
27
+
28
+ def self_and_parents
29
+ parents << self
30
+ end
31
+
32
+ def parents
33
+ parts = to_s.split('/')[0..-2]
34
+ parts.inject([]) { |parents, part| parents << self.class.new(parts[0..parents.size].join('/'), root) }
35
+ end
36
+
37
+ def self_and_descendants
38
+ [self] + descendants
39
+ end
40
+
41
+ def descendants
42
+ Dir[join("**/*.{#{TYPES.join(',')}}")].map { |child| join(child.gsub(/#{to_s}\/?/, '')) }
43
+ end
44
+
45
+ def local
46
+ gsub(root ? "#{root}/" : '', '')
47
+ end
48
+
49
+ def filename
50
+ basename.gsub(extname, '')
51
+ end
52
+
53
+ def join(other)
54
+ self.class.new(super, root)
55
+ # self.class.new(super(other.gsub(/^\//, '')), root)
56
+ end
57
+
58
+ def gsub(pattern, replacement)
59
+ self.class.new(to_s.gsub(pattern, replacement), root)
60
+ end
61
+
62
+ def glob
63
+ paths = Dir[join('**/*')].map { |child| join(child.gsub("#{to_s}/", '')) }
64
+ paths = paths.map { |path| path.filename == 'index' ? path.parent : path }
65
+ paths.sort
66
+ end
67
+
68
+ def find(name)
69
+ path = Dir["#{join(name)}.{#{TYPES.join(',')}}"].first
70
+ self.class.new(path, root) if path
71
+ end
72
+
73
+ def <=>(other)
74
+ root? ? -1 : other.root? ? 1 : to_s <=> other.to_s
75
+ end
76
+
77
+ def ==(other)
78
+ to_s == other.to_s
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,67 @@
1
+ require 'simple_slugs'
2
+
3
+ module Adva
4
+ class Static
5
+ class Import
6
+ module Source
7
+ class Post < Base
8
+ PERMALINK = %r((?:^|/)(\d{4})(?:\-|\/)(\d{1,2})(?:\-|\/)(\d{1,2})(?:\-|\/)(.*)$)
9
+
10
+ class << self
11
+ def recognize(paths)
12
+ posts = paths.map { |path| path.self_and_descendants }.flatten.select { |path| permalink?(path) }
13
+ posts = posts.map { |path| new(path) }
14
+ paths.replace(paths - posts.map(&:permalink_paths).flatten)
15
+ posts
16
+ end
17
+
18
+ def permalink?(path)
19
+ path.to_s =~ PERMALINK
20
+ end
21
+ end
22
+
23
+ def categories
24
+ @categories ||= Array(read.categories).map { |category| category.split(',') }.flatten.map(&:strip)
25
+ end
26
+
27
+ def title
28
+ @title ||= read.title || path_tokens.last.titleize
29
+ end
30
+
31
+ def slug
32
+ @slug ||= read.slug || SimpleSlugs::Slug.new(title).to_s
33
+ end
34
+
35
+ def published_at
36
+ @published_at ||= DateTime.civil(*permalink[0..-2].map(&:to_i))
37
+ end
38
+
39
+ def permalink
40
+ @permalink ||= path_tokens.to_a[0..-2] << slug
41
+ end
42
+
43
+ def permalink_paths
44
+ path.self_and_parents - path.root.self_and_parents
45
+ end
46
+
47
+ def strip_permalink
48
+ path.gsub(Post::PERMALINK, '')
49
+ end
50
+
51
+ def data
52
+ super.merge(:categories => categories, :title => title, :slug => slug, :published_at => published_at)
53
+ end
54
+
55
+ protected
56
+
57
+ def path_tokens
58
+ @path_tokens ||= path.to_s.gsub(/\.\w+$/, '').match(PERMALINK).to_a[1..-1]
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+
67
+