form_bridge 0.0.1.alpha1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 82a9b4af8c6b209a40a1a2204af5c6c36d563c49
4
+ data.tar.gz: 897c12e86bdbe95627d3b597e37ccc57cfd82842
5
+ SHA512:
6
+ metadata.gz: 12bb04d1775c0d461b60f48f64b52e52bbea63c00ee77f0e3e50ecc0031ea11f9148b45eb3e5a9fc0cce8fe67426061b30053fe5bb77c5f93e03b42164029134
7
+ data.tar.gz: 5feaf0a1bc71ac1806e5526fcfb19ae100dbb704e8af9b46680d0f6407707aaaa3ccbfd6e0688b482e52fee6e079836dc01b4faa4a90224c7650a0a55ba10570
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in form_bridge.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # FormBridge
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/form_bridge`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'form_bridge'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install form_bridge
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it ( https://github.com/[my-github-username]/form_bridge/fork )
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "form_bridge"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/form-bridge ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby -Ilib
2
+
3
+ require 'form_bridge'
4
+
5
+ FormBridge::CLI.new(ARGV).start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'form_bridge/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "form_bridge"
8
+ spec.version = FormBridge::VERSION
9
+ spec.authors = ["Tony Pitale"]
10
+ spec.email = ["tpitale@gmail.com"]
11
+
12
+ spec.summary = %q{Bridge a web form to a file for CSV/JSON download}
13
+ spec.description = %q{Bridge a web form to a file for CSV/JSON download}
14
+ spec.homepage = "https://github.com/tpitale/"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.9"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+
24
+ spec.add_runtime_dependency "rack"
25
+ spec.add_runtime_dependency "puma"
26
+ end
@@ -0,0 +1,38 @@
1
+ module FormBridge
2
+ class CLI
3
+ attr_accessor :options
4
+
5
+ def initialize(args)
6
+ self.options = {logger: Logger.new(STDOUT)}
7
+
8
+ OptionParser.new do |parser|
9
+ parser.banner = [
10
+ "Usage: #{@name} -P /tmp/database.db\n",
11
+ " #{@name} --help\n"
12
+ ].compact.join
13
+
14
+ parser.on('-P', '--path PATH') do |path|
15
+ self.options[:db] = FormBridge::Persistance.new(GDBM.new(path))
16
+ end
17
+
18
+ parser.on_tail("-?", "--help", "Display this usage information.") do
19
+ puts "#{parser}\n"
20
+ exit
21
+ end
22
+ end.parse!(args)
23
+ end
24
+
25
+ def start
26
+ FormBridge.map(options) do
27
+ get "/forms/new",
28
+ FormBridge::Endpoint::Forms::New.new(options[:db])
29
+
30
+ get "/forms",
31
+ FormBridge::Endpoint::Forms::Show.new(options[:db])
32
+
33
+ post "/submissions",
34
+ FormBridge::Endpoint::Submissions::Create.new(options[:db])
35
+ end.run
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,21 @@
1
+ module FormBridge
2
+ module Endpoint
3
+ module Forms
4
+ class New
5
+ def initialize(database)
6
+ @database = database
7
+ end
8
+
9
+ def call(request)
10
+ # make a securerandom uuid
11
+ # display URL
12
+ # display instructions
13
+ form = Form.new(@database)
14
+ form.save
15
+
16
+ [200, {"Content-Type" => "text/plain"}, [form.id.to_s]]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ module FormBridge
2
+ module Endpoint
3
+ module Forms
4
+ class Show
5
+ def initialize(database)
6
+ @database = database
7
+ end
8
+
9
+ def call(request)
10
+ id = request.params["id"]
11
+ form = @database.get(id)
12
+
13
+ # return form submissions as json
14
+ data = JSON.dump form.submissions.map(&:as_json)
15
+ [200, {"Content-Type" => "application/json"}, [data]]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module FormBridge
2
+ module Endpoint
3
+ module Submissions
4
+ class Create
5
+ def initialize(database)
6
+ @database = database
7
+ end
8
+
9
+ def call(request)
10
+ location = request.params["_next"]
11
+ form = @database.get(request.params["form_id"])
12
+
13
+ form.submissions << Submission.from_params(request.params)
14
+ form.save
15
+
16
+ [302, {"Location" => location}, []]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ module FormBridge
2
+ class Handler
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def run
8
+ Rack::Handler::Puma.run @app
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,54 @@
1
+ module FormBridge
2
+ class Form
3
+ def self.from_persistance(database, attrs={})
4
+ new(database, {
5
+ id: attrs['id'],
6
+ submissions: Submission.from_persistance(attrs["submissions"] || [])
7
+ })
8
+ end
9
+
10
+ def self.key_for(id)
11
+ ["form", id].join(':')
12
+ end
13
+
14
+ def initialize(database, attributes={})
15
+ @database = database
16
+ @attributes = {submissions: []}.merge(attributes)
17
+ end
18
+
19
+ def key
20
+ self.class.key_for(id)
21
+ end
22
+
23
+ def id
24
+ self[:id] ||= SecureRandom.uuid
25
+ end
26
+
27
+ def submissions
28
+ self[:submissions]
29
+ end
30
+
31
+ def new?
32
+ id.nil?
33
+ end
34
+
35
+ def [](key)
36
+ @attributes[key]
37
+ end
38
+
39
+ def []=(key, value)
40
+ @attributes[key] = value
41
+ end
42
+
43
+ def save
44
+ @database.persist(self)
45
+ end
46
+
47
+ def as_json
48
+ {
49
+ id: id,
50
+ submissions: submissions.map(&:as_json)
51
+ }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ module FormBridge
2
+ class Submission
3
+ def self.type
4
+ self.class.name.downcase
5
+ end
6
+
7
+ def self.from_persistance(collection=[])
8
+ collection.map do |attributes|
9
+ new(id: attributes["id"]).append_all(attributes)
10
+ end
11
+ end
12
+
13
+ def self.from_params(params={})
14
+ new(email: params.delete("_replyto")).append_all(params)
15
+ end
16
+
17
+ def initialize(attributes={})
18
+ @attributes = {id: SecureRandom.uuid}.merge(attributes)
19
+ end
20
+
21
+ def append_all(attributes={})
22
+ puts "Appending:"
23
+ p attributes
24
+
25
+ attributes.each {|k,v| append(k,v)}
26
+ self
27
+ end
28
+
29
+ def append(key, value)
30
+ return if key.start_with?("_") || value.to_s.length < 1
31
+
32
+ @attributes[key.to_sym] = value
33
+ end
34
+
35
+ def as_json
36
+ @attributes
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,20 @@
1
+ module FormBridge
2
+ class Persistance
3
+ def initialize(database)
4
+ @database = database
5
+ end
6
+
7
+ def persist(form)
8
+ @database[form.key] = JSON.dump(form.as_json)
9
+ end
10
+
11
+ def get(id)
12
+ Form.from_persistance(self, JSON.load(raw(id)))
13
+ end
14
+
15
+ private
16
+ def raw(id)
17
+ @database[Form.key_for(id)]
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,94 @@
1
+ module FormBridge
2
+ # middleware which matches rack request
3
+ class Router
4
+ GET = 'GET'
5
+ POST = 'POST'
6
+
7
+ def self.build(options, &block)
8
+ Rack::Builder.new do
9
+ use Rack::CommonLogger
10
+
11
+ run FormBridge::Router.new(options, &block)
12
+ end
13
+ end
14
+
15
+ class Route
16
+ def initialize(verb, path, endpoint)
17
+ @verb = verb
18
+ @path = path
19
+ @endpoint = endpoint
20
+ end
21
+
22
+ def match_path?(request)
23
+ # does request match on path
24
+ request.path == @path
25
+ end
26
+
27
+ def match_verb?(request)
28
+ # does request match on verb
29
+ request.request_method == @verb
30
+ end
31
+
32
+ def call(request)
33
+ @endpoint.call(request)
34
+ end
35
+ end
36
+
37
+ class NotFoundRoute
38
+ def match_path?(*)
39
+ true
40
+ end
41
+
42
+ def match_verb?(*)
43
+ true
44
+ end
45
+
46
+ def call(*)
47
+ [404, { "Content-Type" => "text/plain" }, ["NOT_FOUND"]]
48
+ end
49
+ end
50
+
51
+ attr_reader :options
52
+
53
+ def initialize(options, &block)
54
+ @options = options
55
+ @routes = [] # this is fine for now because we only have two routes
56
+
57
+ instance_eval(&block)
58
+
59
+ # we want to force this as the last
60
+ @routes << NotFoundRoute.new
61
+ end
62
+
63
+ def logger
64
+ options[:logger]
65
+ end
66
+
67
+ def get(path, endpoint)
68
+ route(GET, path, endpoint)
69
+ end
70
+
71
+ def post(path, endpoint)
72
+ route(POST, path, endpoint)
73
+ end
74
+
75
+ def route(verb, path, endpoint)
76
+ @routes << Route.new(verb, path, endpoint)
77
+ end
78
+
79
+ def call(env)
80
+ request = Rack::Request.new(env)
81
+
82
+ begin
83
+ @routes.detect do |route|
84
+ route.match_verb?(request) && route.match_path?(request)
85
+ end.call(request)
86
+ rescue => e
87
+ puts e.message
88
+ puts e.backtrace
89
+
90
+ [500, { "Content-Type" => "text/plain" }, ["SERVER_ERROR"]]
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,3 @@
1
+ module FormBridge
2
+ VERSION = "0.0.1.alpha1"
3
+ end
@@ -0,0 +1,26 @@
1
+ require "form_bridge/version"
2
+ require "logger"
3
+ require "optparse"
4
+ require "securerandom"
5
+ require "json"
6
+ require "gdbm"
7
+ require "rack"
8
+ require "rack/handler/puma"
9
+
10
+ module FormBridge
11
+ module_function def map(options, &block)
12
+ FormBridge::Handler.new(FormBridge::Router.build(options, &block))
13
+ end
14
+ end
15
+
16
+ require "form_bridge/cli"
17
+ require "form_bridge/router"
18
+ require "form_bridge/handler"
19
+ require "form_bridge/persistance"
20
+
21
+ require "form_bridge/models/form" # => FormBridge::Form
22
+ require "form_bridge/models/submission" # => FormBridge::Submission
23
+
24
+ require "form_bridge/endpoint/forms/new"
25
+ require "form_bridge/endpoint/forms/show"
26
+ require "form_bridge/endpoint/submissions/create"
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: form_bridge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.alpha1
5
+ platform: ruby
6
+ authors:
7
+ - Tony Pitale
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: puma
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Bridge a web form to a file for CSV/JSON download
70
+ email:
71
+ - tpitale@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - ".travis.yml"
79
+ - Gemfile
80
+ - README.md
81
+ - Rakefile
82
+ - bin/console
83
+ - bin/form-bridge
84
+ - bin/setup
85
+ - form_bridge.gemspec
86
+ - lib/form_bridge.rb
87
+ - lib/form_bridge/cli.rb
88
+ - lib/form_bridge/endpoint/forms/new.rb
89
+ - lib/form_bridge/endpoint/forms/show.rb
90
+ - lib/form_bridge/endpoint/submissions/create.rb
91
+ - lib/form_bridge/handler.rb
92
+ - lib/form_bridge/models/form.rb
93
+ - lib/form_bridge/models/submission.rb
94
+ - lib/form_bridge/persistance.rb
95
+ - lib/form_bridge/router.rb
96
+ - lib/form_bridge/version.rb
97
+ homepage: https://github.com/tpitale/
98
+ licenses: []
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">"
112
+ - !ruby/object:Gem::Version
113
+ version: 1.3.1
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.4.5
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Bridge a web form to a file for CSV/JSON download
120
+ test_files: []