snipsnap-extensions 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e165c7d5e1c7c34e4bc0239753a4abc94ef0ba87
4
+ data.tar.gz: aec80eff20c30345fb0374893a47703b88fe9b05
5
+ SHA512:
6
+ metadata.gz: 64b173817b5d6d2fbd515cc5c4aca81349a6bcf0185c557e04c64022f2573574b4aa92369288bfb5296323e51f7c3beef0135fb83df9d6550a840bd2091bf846
7
+ data.tar.gz: b8aa68392360c1c8343e40b8d729b810a44feface3be7eb5c35760a70170de04c5bae7e54912e5d3c905bc386d5094f06417a880fdb5c32cbd5abc1a98e95cff
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in snipsnap-extensions.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Sean Doyle
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,149 @@
1
+ # Snipsnap::Extensions
2
+
3
+ Sinatra Extensions from the `SnipSnap` / `Goodfor` codebases
4
+
5
+ ## Installation
6
+
7
+ Since this is a private repository, you'll either need to setup your deployment box to have proper GitHub credentials, or more easily you need to vendor the gem.
8
+
9
+ ```console
10
+ $ mkdir -p vendor/private_gems
11
+ $ git clone git@github.com:snipsnap/snipsnap-extensions.git vendor/private_gems/snipsnap-extensions
12
+ ```
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'snipsnap-extensions', '0.0.1', path: 'vendor/private_gems/snipsnap-extensions'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ ```console
23
+ $ bundle
24
+ ```
25
+
26
+ ## Usage
27
+
28
+ In your `Sinatra::Base` file, require the extension and then `register` it
29
+
30
+ For example, to include the `SnipSnap::CORSExtension`,
31
+
32
+ ```ruby
33
+ # app.rb
34
+ require 'snipsnap/extensions/cors'
35
+
36
+ # ...
37
+ class App < Sinatra::Base
38
+ # ...
39
+ register SnipSnap::CORSExtension
40
+ end
41
+ ```
42
+
43
+ ### Require All
44
+
45
+ ```ruby
46
+ # app.rb
47
+ require 'snipsnap/extensions/all'
48
+
49
+ # ...
50
+ class App < Sinatra::Base
51
+ # ...
52
+ register SnipSnap::AuthExtension
53
+ register SnipSnap::CORSExtension
54
+ # ...
55
+ end
56
+ ```
57
+
58
+ ## Extensions
59
+
60
+ ## SnipSnap::ActionMailerExtension
61
+
62
+ Require Path: 'snipsnap/extensions/action_mailer'
63
+
64
+ Optional:
65
+
66
+ * `ENV['EMAIL_ADDRESS']` defaults to "smtp.sendgrid.net"
67
+ * `ENV['URL_ROOT']` for prepending email URLs with `url_for(path)`
68
+
69
+ Requires:
70
+ * `gem 'actionmailer'`
71
+ * `gem 'letter_opener'` in development
72
+ * `ENV['EMAIL_DOMAIN']` for outgoing mail domain
73
+ * `ENV['EMAIL_USER_NAME']` for sendgrid username
74
+ * `ENV['EMAIL_PASSWORD']` for sendgrid password
75
+
76
+ ## SnipSnap::ActiveRecord
77
+
78
+ Require path: `snipsnap/extensions/active_record`
79
+
80
+ Requires:
81
+ * `gem 'activerecord'`
82
+ * `gem 'sinatra-activerecord'`
83
+
84
+ # SnipSnap::Auth
85
+
86
+ Require Path: `snipsnap/extensions/auth`
87
+
88
+ Requires:
89
+
90
+ * `Guest` model to act as an unfound user
91
+ * include the `SnipSnap::Guest` mixin into your Guest class
92
+
93
+ * include the `SnipSnap::User` mixin into your
94
+ * `User` model that
95
+ * responds to `authenticate` to check for password match (matching the `has_secure_password` interface)
96
+ * responds to `authorized?`
97
+
98
+ ## SnipSnap::CORSExtension
99
+
100
+ Require Path: `snipsnap/extensions/cors`
101
+
102
+ ## SnipSnap::DeliveryExtension
103
+
104
+ Require Path: `snipsnap/extensions/delivery`
105
+
106
+ ## SnipSnap::JSONBodyExtension
107
+
108
+ Require Path: `snipsnap/extensions/json_body`
109
+
110
+ ## SnipSnap::LoggingExtension
111
+
112
+ Require Path: `snipsnap/extensions/logging`
113
+
114
+ ## SnipSnap::PaperclipExtension
115
+
116
+ Setup paperclip file management
117
+
118
+ Require Path: `snipsnap/extensions/paperclip`
119
+
120
+ Requires:
121
+ * `gem 'paperclip'`
122
+ * `imagemagick` installed on system
123
+
124
+ ## SnipSnap::PlatformDetectExtension
125
+
126
+ Require Path: `snipsnap/extensions/platform_detect`
127
+
128
+ ## SnipSnap::SprocketsExtension
129
+
130
+ Require Path: `snipsnap/extensions/sprockets`
131
+
132
+ Optional:
133
+
134
+ * `ENV['ASSET_HOST']` prepended to asset URLs
135
+ * `ENV['API_ROOT']` prepended to API AJAX calls
136
+
137
+ Required:
138
+
139
+ * `gem 'sprockets'`
140
+ * `gem 'sass'`
141
+ * `gem 'coffee-script'`
142
+
143
+ ## Contributing
144
+
145
+ 1. Fork it
146
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
147
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
148
+ 4. Push to the branch (`git push origin my-new-feature`)
149
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,7 @@
1
+ require "snipsnap/extensions/version"
2
+
3
+ module SnipSnap
4
+ module Extensions
5
+ # Your code goes here...
6
+ end
7
+ end
@@ -0,0 +1,62 @@
1
+ # # SnipSnap::ActionMailerExtension
2
+ #
3
+ # Require Path: 'snipsnap/extensions/action_mailer'
4
+ #
5
+ # Optional:
6
+ #
7
+ # * `ENV['EMAIL_ADDRESS']` defaults to "smtp.sendgrid.net"
8
+ # * `ENV['URL_ROOT']` for prepending email URLs with `url_for(path)`
9
+ #
10
+ # Requires:
11
+ # * `gem 'actionmailer'`
12
+ # * `gem 'letter_opener'` in development
13
+ # * `ENV['EMAIL_DOMAIN']` for outgoing mail domain
14
+ # * `ENV['EMAIL_USER_NAME']` for sendgrid username
15
+ # * `ENV['EMAIL_PASSWORD']` for sendgrid password
16
+ #
17
+ require 'action_mailer'
18
+
19
+ module SnipSnap::ActionMailerExtension
20
+ def self.registered(app)
21
+ ActionMailer::Base.class_eval do
22
+ helper do
23
+ def url_for(path)
24
+ url_root = ENV.fetch("URL_ROOT", "")
25
+ [url_root, path].join
26
+ end
27
+ end
28
+ end
29
+
30
+ app.configure do
31
+ ActionMailer::Base.tap do |config|
32
+ config.delivery_method = :smtp
33
+ config.view_paths = app.root
34
+ config.raise_delivery_errors = true
35
+ config.smtp_settings = {
36
+ :authentication => :plain,
37
+ :enable_starttls_auto => true,
38
+ :port => 25,
39
+ :address => ENV["EMAIL_ADDRESS"] || "smtp.sendgrid.net",
40
+ :domain => ENV["EMAIL_DOMAIN"],
41
+ :user_name => ENV["EMAIL_USER_NAME"],
42
+ :password => ENV["EMAIL_PASSWORD"]
43
+ }
44
+ end
45
+ end
46
+
47
+ app.configure :development do
48
+ require 'letter_opener'
49
+
50
+ ActionMailer::Base.tap do |config|
51
+ config.add_delivery_method :letter_opener,
52
+ LetterOpener::DeliveryMethod,
53
+ location: app.root + "/tmp/letter_opener"
54
+ config.delivery_method = :letter_opener
55
+ end
56
+ end
57
+
58
+ app.configure :test do
59
+ config.delivery_method = :test
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,27 @@
1
+ # # SnipSnap::ActiveRecord
2
+ #
3
+ # Requires:
4
+ # * `gem 'activerecord'`
5
+ # * `gem 'sinatra-activerecord'`
6
+ #
7
+
8
+ require 'sinatra/activerecord'
9
+ require 'active_record'
10
+
11
+ module SnipSnap::ActiveRecordExtension
12
+ def self.registered(app)
13
+ app.register Sinatra::ActiveRecordExtension
14
+
15
+ app.error ActiveRecord::RecordNotFound do
16
+ halt 404
17
+ end
18
+
19
+ app.error ActiveRecord::RecordInvalid do
20
+ halt 422
21
+ end
22
+
23
+ app.error ActiveRecord::RecordNotUnique do
24
+ halt 409
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ Dir[File.join(File.dirname(__FILE__), "**", "*.rb")].each do |file|
2
+ require file unless file == __FILE__
3
+ end
@@ -0,0 +1,79 @@
1
+ # # SnipSnap::Auth
2
+ #
3
+ # Require Path: `snipsnap/extensions/auth`
4
+ #
5
+ # Requires:
6
+ #
7
+ # * `Guest` model to act as an unfound user
8
+ # * include the `SnipSnap::Guest` mixin into your Guest class
9
+ #
10
+ # * include the `SnipSnap::User` mixin into your
11
+ # * `User` model that
12
+ # * responds to `authenticate` to check for password match (matching the `has_secure_password` interface)
13
+ # * responds to `authorized?`
14
+ #
15
+
16
+ require 'snipsnap/models/user'
17
+ require 'snipsnap/models/guest'
18
+
19
+ module SnipSnap::AuthExtension
20
+ def self.registered(app)
21
+ app.helpers Helpers
22
+
23
+ app.error 401..403 do
24
+ headers = {
25
+ 'WWW-Authenticate' => %(Basic realm="Restricted Area")
26
+ }
27
+ body = {
28
+ error: 'Unauthorized'
29
+ }.to_json
30
+
31
+ halt 401, headers, body
32
+ end
33
+ end
34
+
35
+ module Helpers
36
+ def restricted!
37
+ halt 403 unless current_user.admin?
38
+ end
39
+
40
+ def protected!
41
+ halt 401 unless authorized?
42
+ end
43
+
44
+ # XXX cache result after going through logic once?
45
+ def authorized?
46
+ current_user.authorized?
47
+ end
48
+
49
+ def current_user
50
+ @current_user ||= begin
51
+ auth ||= Rack::Auth::Basic::Request.new(request.env)
52
+
53
+ user = nil
54
+
55
+ if auth.provided? && auth.basic? && auth.credentials
56
+ email, password, _ = auth.credentials
57
+
58
+ logger.info "Credentials for #{email}"
59
+
60
+ # XXX URGENT NEED TO CHECK ACTUAL FACEBOOK TOKEN!
61
+ @facebook_user = password.size > 16
62
+
63
+ user = User.for(email)
64
+
65
+ unless @facebook_user
66
+ user = user.authenticate(password)
67
+ end
68
+ else
69
+ logger.info "No credentials"
70
+ end
71
+ user || Guest.new
72
+ end
73
+ end
74
+
75
+ def user_for_id(id)
76
+ id == 'me' ? current_user : User.find(id)
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,21 @@
1
+ # # SnipSnap::CORSExtension
2
+ #
3
+ # Require Path: `snipsnap/extensions/cors`
4
+ #
5
+ module SnipSnap::CORSExtension
6
+ def self.registered(app)
7
+ app.before do
8
+ # CORS HEADERS
9
+ headers \
10
+ "Access-Control-Allow-Origin" => "*",
11
+ "Access-Control-Allow-Methods" => "POST, GET, PUT, DELETE, OPTIONS",
12
+ "Access-Control-Allow-Credentials" => "true"
13
+
14
+ # Handle HTTP OPTIONS method used by jQuery
15
+ if request.request_method == 'OPTIONS'
16
+ headers["Access-Control-Allow-Headers"] = "Origin, Content-type, Accept, Authorization"
17
+ halt 200
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,34 @@
1
+ # # SnipSnap::DeliveryExtension
2
+ #
3
+ # Require Path: `snipsnap/extensions/delivery`
4
+ #
5
+
6
+ module SnipSnap::DeliveryExtension
7
+ def self.registered(app)
8
+ app.helpers Helpers
9
+ end
10
+
11
+ module Helpers
12
+ def deliver(response)
13
+ halt 404 if response.nil?
14
+
15
+ if !response.is_a?(Hash) && response.respond_to?(:map)
16
+ response = response.map{|item| to_api(item) }
17
+ end
18
+
19
+ content_type :json
20
+
21
+ to_api(response).to_json
22
+ end
23
+
24
+ private
25
+
26
+ def to_api(response)
27
+ if response.respond_to?(:api_hash)
28
+ response.api_hash
29
+ else
30
+ response
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,33 @@
1
+ require 'i18n'
2
+ require 'i18n/backend/fallbacks'
3
+
4
+ module SnipSnap::I18nExtension
5
+ def self.registered(app)
6
+ app.use Rack::Locale
7
+
8
+ app.configure do
9
+ I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
10
+ I18n.load_path = Dir[File.join(app.settings.root, 'config', 'locales', '*.yml')]
11
+ I18n.backend.load_translations
12
+ end
13
+
14
+ app.helpers Helpers
15
+ end
16
+
17
+ module Helpers
18
+ def t(*args)
19
+ I18n.t(*args)
20
+ end
21
+
22
+ def l(*args)
23
+ I18n.l(*args)
24
+ end
25
+
26
+ def find_template(views, name, engine, &block)
27
+ I18n.fallbacks[I18n.locale].each do |locale|
28
+ super(views, "#{name}.#{locale}", engine, &block)
29
+ end
30
+ super(views, name, engine, &block)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ # # SnipSnap::JSONBodyExtension
2
+ #
3
+ # Require Path: `snipsnap/extensions/json_body`
4
+ #
5
+ module SnipSnap::JSONBodyExtension
6
+ def self.registered(app)
7
+ app.before do
8
+ # If there's a body, assume it is JSON and try to parse it.
9
+
10
+ body = ''
11
+
12
+ begin
13
+ body = request.env["rack.input"].read
14
+ @body = body
15
+ request.env["rack.input"].rewind
16
+ rescue => e
17
+ logger.debug "ERROR reading rack.input: #{e.inspect}"
18
+ end
19
+
20
+ @json = nil
21
+
22
+ # XXX Check for application/json content type?
23
+ if body.index("{") or body.index("[")
24
+ begin
25
+ @json = JSON.parse(body)
26
+ puts "JSON: "
27
+ puts JSON.pretty_generate(@json)
28
+ rescue
29
+ logger.info "ERROR: Could not parse body as JSON"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ # # SnipSnap::LoggingExtension
2
+ #
3
+ # Require Path: `snipsnap/extensions/logging`
4
+ #
5
+ module SnipSnap::LoggingExtension
6
+ def self.registered(app)
7
+ app.configure do
8
+ app.enable :logging
9
+ file = File.new("#{app.settings.root}/log/#{app.settings.environment}.log", 'a+')
10
+ file.sync = true
11
+ app.use Rack::CommonLogger, file
12
+ end
13
+
14
+ app.before do
15
+ # Some simple logging
16
+
17
+ #puts request.env['REQUEST_METHOD'] + ": " + request.env['PATH_INFO']
18
+ puts "PARAMS: " + params.inspect
19
+ puts "USER AGENT: " + request.env['HTTP_USER_AGENT'].to_s
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,56 @@
1
+ # # SnipSnap::PaperclipExtension
2
+ #
3
+ # Require Path: `snipsnap/extensions/paperclip`
4
+ #
5
+ # Setup paperclip file management
6
+ #
7
+ # Requires:
8
+ # * `gem 'paperclip'`
9
+ # * `imagemagick` installed on system
10
+ #
11
+
12
+ require 'paperclip'
13
+
14
+ module SnipSnap::PaperclipExtension
15
+ def self.registered(app)
16
+ app.configure do
17
+ Paperclip.io_adapters.register FileAdapter do |target|
18
+ begin
19
+ target.is_a?(Hash) && Tempfile === target[:tempfile]
20
+ rescue => e
21
+ false
22
+ end
23
+ end
24
+
25
+ Paperclip.interpolates :rails_root do |attachment, style|
26
+ app.root
27
+ end
28
+
29
+ Paperclip.interpolates :guid do |attachment, style|
30
+ attachment.instance.guid
31
+ end
32
+
33
+ Paperclip.options[:command] = `which convert`
34
+ Paperclip::Attachment.default_options.tap do |config|
35
+ config[:url] = "/:attachment/:guid-:style.:extension"
36
+ end
37
+ end
38
+ end
39
+
40
+ class FileAdapter < Paperclip::AbstractAdapter
41
+ def initialize(target)
42
+ @target = target[:tempfile]
43
+ cache_current_values(target)
44
+ end
45
+
46
+ private
47
+
48
+ def cache_current_values(target)
49
+ self.original_filename = target[:filename]
50
+ self.original_filename ||= File.basename(@target.path)
51
+ @tempfile = copy_to_tempfile(@target)
52
+ @content_type = Paperclip::ContentTypeDetector.new(@target.path).detect
53
+ @size = File.size(@target)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,13 @@
1
+ # # SnipSnap::PlatformDetectExtension
2
+ #
3
+ # Require Path: `snipsnap/extensions/platform_detect`
4
+ #
5
+ module SnipSnap::PlatformDetectExtension
6
+ def self.registered(app)
7
+ app.before do
8
+ user_agent = request.env['HTTP_USER_AGENT'].to_s
9
+
10
+ @is_android = user_agent =~ /Android/ || user_agent =~ /Linux/
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,61 @@
1
+ # # SnipSnap::SprocketsExtension
2
+ #
3
+ # Require Path: `snipsnap/extensions/sprockets`
4
+ #
5
+ # Optional:
6
+ # * `ENV['ASSET_HOST']` prepended to asset URLs
7
+ # * `ENV['API_ROOT']` prepended to API AJAX calls
8
+ #
9
+ # Required:
10
+ # * `gem 'sprockets'`
11
+ # * `gem 'sass'`
12
+ # * `gem 'coffee-script'`
13
+ #
14
+
15
+ module SnipSnap::SprocketsExtension
16
+ def self.registered(app)
17
+ app.helpers Helpers
18
+
19
+ app.configure do
20
+ app.set :static, true
21
+ app.set :views, ->{ File.join(app.root, "app", "views") }
22
+ app.set :assets, assets = Sprockets::Environment.new(app.root)
23
+ app.set :asset_host, ENV.fetch("ASSET_HOST", "")
24
+
25
+ assets.append_path('app/assets/javascripts')
26
+ assets.append_path('app/assets/stylesheets')
27
+ assets.append_path('app/assets/images')
28
+ assets.append_path('app/assets/fonts')
29
+
30
+ assets.append_path('vendor/assets/javascripts')
31
+ assets.append_path('vendor/assets/stylesheets')
32
+ assets.append_path('vendor/assets/images')
33
+ assets.append_path('vendor/assets/fonts')
34
+
35
+ assets.context_class.class_eval do
36
+ cattr_accessor :settings
37
+
38
+ include SnipSnap::SprocketsExtension::Helpers
39
+ end
40
+ assets.context_class.settings = app.settings
41
+ end
42
+
43
+ app.get '/assets/*' do
44
+ env['PATH_INFO'].sub!(%r{^/assets}, '')
45
+ settings.assets.call(env)
46
+ end
47
+ end
48
+
49
+ module Helpers
50
+ def api_for(path)
51
+ url_root = ENV.fetch("API_ROOT", "")
52
+ [url_root, path].join
53
+ end
54
+
55
+ def asset_path(name, options={})
56
+ asset = settings.assets[name]
57
+ raise "Unknown asset: #{name}" unless asset
58
+ "#{settings.asset_host}/assets/#{asset.digest_path}"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,5 @@
1
+ module SnipSnap
2
+ module Extensions
3
+ VERSION = "0.0.3"
4
+ end
5
+ end
@@ -0,0 +1,25 @@
1
+ module SnipSnap::Guest
2
+ def id
3
+ 0
4
+ end
5
+
6
+ def authenticate(*)
7
+ false
8
+ end
9
+
10
+ def authorized?
11
+ false
12
+ end
13
+
14
+ def password
15
+ nil
16
+ end
17
+
18
+ def password_reset?
19
+ false
20
+ end
21
+
22
+ def admin?
23
+ false
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ module SnipSnap::User
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def authenticate(email, password)
6
+ self.for(email).authenticate(password)
7
+ end
8
+
9
+ def for(email)
10
+ find_by(email: email) || Guest.new
11
+ end
12
+ end
13
+ end
@@ -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 'snipsnap/extensions/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "snipsnap-extensions"
8
+ spec.version = SnipSnap::Extensions::VERSION
9
+ spec.authors = ["Sean Doyle"]
10
+ spec.email = ["sean.p.doyle24@gmail.com"]
11
+ spec.description = %q{Sinatra Extensions for SnipSnap}
12
+ spec.summary = %q{Sinatra Extensions for SnipSnap}
13
+ spec.homepage = "https://github.com/snipsnap/snipsnap-extensions"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+
22
+ spec.add_dependency "sinatra"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snipsnap-extensions
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Sean Doyle
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Sinatra Extensions for SnipSnap
56
+ email:
57
+ - sean.p.doyle24@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/snipsnap/extensions.rb
68
+ - lib/snipsnap/extensions/action_mailer.rb
69
+ - lib/snipsnap/extensions/active_record.rb
70
+ - lib/snipsnap/extensions/all.rb
71
+ - lib/snipsnap/extensions/auth.rb
72
+ - lib/snipsnap/extensions/cors.rb
73
+ - lib/snipsnap/extensions/delivery.rb
74
+ - lib/snipsnap/extensions/i18n.rb
75
+ - lib/snipsnap/extensions/json_body.rb
76
+ - lib/snipsnap/extensions/logging.rb
77
+ - lib/snipsnap/extensions/paperclip.rb
78
+ - lib/snipsnap/extensions/platform_detect.rb
79
+ - lib/snipsnap/extensions/sprockets.rb
80
+ - lib/snipsnap/extensions/version.rb
81
+ - lib/snipsnap/models/guest.rb
82
+ - lib/snipsnap/models/user.rb
83
+ - snipsnap-extensions.gemspec
84
+ homepage: https://github.com/snipsnap/snipsnap-extensions
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.0.0
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Sinatra Extensions for SnipSnap
108
+ test_files: []