adva-static 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,92 +0,0 @@
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
@@ -1,82 +0,0 @@
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
@@ -1,15 +0,0 @@
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
@@ -1,59 +0,0 @@
1
- require 'fileutils'
2
-
3
- module Adva
4
- class Static
5
- module Rack
6
- class Export
7
- include Request
8
-
9
- attr_reader :app, :target, :store
10
-
11
- def initialize(app, options = {})
12
- @app = app
13
- @target = Pathname.new(options[:target] || File.expand_path('./export'))
14
- @store = Adva::Static::Export::Store.new(target)
15
- end
16
-
17
- def call(env)
18
- path = env['PATH_INFO'].dup # gets modified by routing_filter
19
- app.call(env).tap do |status, headers, response|
20
- export(path, response) if export?(env, status)
21
- if headers.key?(PURGE_HEADER)
22
- paths = normalize_paths(headers[PURGE_HEADER])
23
- paths.each do |path|
24
- purge(path)
25
- request(path)
26
- end
27
- end
28
- end
29
- end
30
-
31
- protected
32
-
33
- def export?(env, status)
34
- env[STORE_HEADER].present? and status == 200
35
- end
36
-
37
- def export(path, response)
38
- page = Adva::Static::Export::Page.new(path, response)
39
- Adva.out.puts " storing #{page.url.filename}"
40
- store.write(page.url, page.body)
41
- end
42
-
43
- def purge(path)
44
- Adva.out.puts " purging #{path}"
45
- store.purge(Adva::Static::Export::Path.new(path))
46
- end
47
-
48
- def request(path)
49
- super('GET', Adva::Static::Export::Path.new(path), STORE_HEADER => true)
50
- end
51
-
52
- def normalize_paths(paths)
53
- paths = paths.split("\n") if paths.is_a?(String)
54
- Array(paths)
55
- end
56
- end
57
- end
58
- end
59
- end
@@ -1,39 +0,0 @@
1
- require 'rack/utils'
2
-
3
- module Adva
4
- class Static
5
- module Rack
6
- module Request
7
- protected
8
- def request(method, path, params = {})
9
- Adva.out.puts " #{params['_method'] ? params['_method'].upcase : method} #{path} "
10
- call(env_for(method, path, params)).tap do |status, headers, response|
11
- Adva.out.puts " => #{status} " + (status == 302 ? "(Location: #{headers['Location']})" : '')
12
- Adva.out.puts response if status == 500
13
- end
14
- end
15
-
16
- def env_for(method, path, params)
17
- ::Rack::MockRequest.env_for("http://#{site.host}#{path}", :method => method,
18
- :input => ::Rack::Utils.build_nested_query(params),
19
- 'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
20
- 'HTTP_AUTHORIZATION' => 'Basic ' + ["#{username}:#{password}"].pack('m*'),
21
- STORE_HEADER => params[STORE_HEADER]
22
- )
23
- end
24
-
25
- def username
26
- 'admin@admin.org' # TODO read from conf/auth.yml or something
27
- end
28
-
29
- def password
30
- 'admin!'
31
- end
32
-
33
- def site
34
- @site ||= Site.first || raise('could not find any site') # FIXME
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,40 +0,0 @@
1
- require 'rack/utils'
2
-
3
- module Adva
4
- class Static
5
- module Rack
6
- class Static < ::Rack::File
7
- attr_reader :app, :root
8
-
9
- def initialize(app, root)
10
- @app = app
11
- @root = root
12
- Adva.out.puts "serving from #{root}"
13
- end
14
-
15
- def call(env)
16
- if get?(env) && path = static(env)
17
- super(env.merge('PATH_INFO' => path))
18
- else
19
- app.call(env)
20
- end
21
- end
22
-
23
- protected
24
-
25
- def static(env)
26
- path = env['PATH_INFO'].chomp('/')
27
- [path, "#{path}.html", "#{path}/index.html"].detect { |path| file?(path) }
28
- end
29
-
30
- def file?(path)
31
- File.file?(File.join(root, ::Rack::Utils.unescape(path)))
32
- end
33
-
34
- def get?(env)
35
- env['REQUEST_METHOD'] == 'GET'
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,88 +0,0 @@
1
- require 'watchr'
2
-
3
- module Adva
4
- class Static
5
- module Rack
6
- class Watch
7
- autoload :Handler, 'adva/static/watch/handler'
8
-
9
- include Request
10
-
11
- attr_reader :app, :dir, :watch
12
-
13
- delegate :call, :to => :app
14
-
15
- def initialize(app, options = {}, &block)
16
- @app = app
17
- @dir = Pathname.new(options[:dir] || File.expand_path('import'))
18
- dir.mkpath
19
- run!
20
- end
21
-
22
- def update(path, event_type = nil)
23
- Adva.out.puts "\n#{event_type}: #{path}"
24
- import = Adva::Static::Import.new(:source => dir)
25
- request = import.request_for(path)
26
- status, headers, response = self.request('POST', request.path, request.params)
27
- get(path) if !request.destroy? && status == 302
28
- rescue Exception => e
29
- Adva.out.puts e.message
30
- e.backtrace.each { |line| puts Adva.out.line }
31
- end
32
-
33
- def get(path)
34
- import = Adva::Static::Import.new(:source => dir)
35
- request = import.request_for(path)
36
- self.request('GET', request.public_path, STORE_HEADER => true)
37
- rescue Exception => e
38
- Adva.out.puts e.message
39
- e.backtrace.each { |line| Adva.out.puts line }
40
- end
41
-
42
- protected
43
-
44
- def run!
45
- @watch = fork { watch!(Adva.out) }
46
- at_exit { kill_watch }
47
- end
48
-
49
- def watch!(out)
50
- Adva.out.puts "watching #{dir} for changes"
51
- Dir.chdir(dir)
52
- handler.listen
53
- rescue SignalException, SystemExit
54
- rescue Exception => e
55
- p e
56
- e.backtrace.each { |line| puts line }
57
- end
58
-
59
- def trap_interrupt
60
- Signal.trap('INT') do
61
- if Time.now - @interrupt < 1
62
- exit
63
- else
64
- STDERR.puts "\nReloading watched paths ... interrupt again to exit."
65
- handler.refresh(watched_paths)
66
- end
67
- @interrupt = Time.now
68
- end
69
- @interrupt = Time.now
70
- end
71
-
72
- def handler
73
- @handler ||= Adva::Static::Watch::Handler.new(self, dir.join("**/*.{#{Import::Source::TYPES.join(',')}}"))
74
- end
75
-
76
- def kill_watch
77
- Process.kill('TERM', watch)
78
- end
79
-
80
- def watched_paths
81
- paths = Dir[dir.join('**/*')].map {|path| Pathname(path).expand_path }
82
- paths << Pathname.new(__FILE__) if paths.empty?
83
- paths
84
- end
85
- end
86
- end
87
- end
88
- end
@@ -1,68 +0,0 @@
1
- require 'core_ext/ruby/kernel/silence_stream'
2
-
3
- module Adva
4
- class Static
5
- class Setup
6
- attr_reader :app, :root, :source, :target, :host, :title, :remote
7
-
8
- def initialize(options)
9
- @app = options[:app] || Rails.application
10
- @root = Pathname.new(options[:root] || Dir.pwd)
11
- @source = root.join(options[:source] || 'import')
12
- @target = root.join(options[:target] || 'export')
13
- @remote = options[:remote]
14
- @host = options[:host] || 'example.org'
15
- @title = options[:title] || host
16
-
17
- Adva.out = StringIO.new('')
18
- end
19
-
20
- def run
21
- setup_directories
22
- initial_import_and_export
23
- setup_source_repository
24
- setup_export_repository
25
- end
26
-
27
- def setup_directories
28
- source.mkdir rescue Errno::EEXIST
29
- target.mkdir rescue Errno::EEXIST
30
- site = source.join('site.yml')
31
- File.open(site, 'w+') { |f| f.write(YAML.dump(:host => host, :title => title)) } unless site.exist?
32
- end
33
-
34
- def initial_import_and_export
35
- Import.new(:source => source).run
36
- Export.new(app, :target => target).run
37
- end
38
-
39
- def setup_source_repository
40
- root.join('.gitignore').rmtree rescue Errno::ENOENT
41
- root.join('.git').rmtree rescue Errno::ENOENT
42
-
43
- File.open(root.join('.gitignore'), 'w+') { |f| f.write('export') }
44
-
45
- Dir.chdir(root) do
46
- `git init`
47
- `git add .`
48
- `git commit -am '#{host} source'`
49
- `git branch source`
50
- `git checkout --quiet source`
51
- `git branch -D master`
52
- `git remote add origin #{remote} -t source` if remote
53
- end
54
- end
55
-
56
- def setup_export_repository
57
- root.join('export/.git').rmtree rescue Errno::ENOENT
58
-
59
- Dir.chdir(target) do
60
- `git init`
61
- `git add .`
62
- `git commit -am '#{host} export'`
63
- `git remote add origin #{remote} -t master` if remote
64
- end
65
- end
66
- end
67
- end
68
- end