├── .gitignore
├── .tool-versions
├── .travis.yml
├── Appraisals
├── Gemfile
├── Gemfile.lock
├── MIT-LICENSE
├── README.md
├── Rakefile
├── app
├── assets
│ ├── images
│ │ └── pointless_feedback
│ │ │ └── .gitkeep
│ ├── javascripts
│ │ └── pointless_feedback
│ │ │ └── application.js
│ └── stylesheets
│ │ └── pointless_feedback
│ │ └── application.css
├── controllers
│ └── pointless_feedback
│ │ └── messages_controller.rb
├── helpers
│ └── pointless_feedback
│ │ └── application_helper.rb
├── mailers
│ └── pointless_feedback
│ │ └── feedback_mailer.rb
├── models
│ └── pointless_feedback
│ │ └── message.rb
└── views
│ ├── layouts
│ └── pointless_feedback
│ │ └── application.html.erb
│ └── pointless_feedback
│ ├── feedback_mailer
│ └── feedback.html.erb
│ └── messages
│ └── new.html.erb
├── config
├── locales
│ └── en.yml
└── routes.rb
├── db
└── migrate
│ ├── 20130501182659_create_pointless_feedback_messages.rb
│ └── 20220518205500_add_url_to_pointless_feedback_messages.rb
├── gemfiles
├── rails_40.gemfile
├── rails_40.gemfile.lock
├── rails_41.gemfile
├── rails_41.gemfile.lock
├── rails_42.gemfile
└── rails_42.gemfile.lock
├── lib
├── generators
│ ├── pointless_feedback
│ │ ├── install_generator.rb
│ │ └── views_generator.rb
│ └── templates
│ │ └── pointless_feedback.rb
├── pointless_feedback.rb
├── pointless_feedback
│ ├── captcha.rb
│ ├── controllers
│ │ └── helpers.rb
│ ├── engine.rb
│ └── version.rb
└── tasks
│ └── pointless_feedback_tasks.rake
├── pointless_feedback.gemspec
├── script
└── rails
└── test
├── dummy
├── README.rdoc
├── Rakefile
├── app
│ ├── assets
│ │ ├── javascripts
│ │ │ └── application.js
│ │ └── stylesheets
│ │ │ └── application.css
│ ├── controllers
│ │ ├── application_controller.rb
│ │ └── home_controller.rb
│ ├── helpers
│ │ └── application_helper.rb
│ ├── mailers
│ │ └── .gitkeep
│ ├── models
│ │ └── .gitkeep
│ └── views
│ │ ├── home
│ │ └── index.html.erb
│ │ └── layouts
│ │ └── application.html.erb
├── config.ru
├── config
│ ├── application.rb
│ ├── boot.rb
│ ├── database.yml
│ ├── environment.rb
│ ├── environments
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── test.rb
│ ├── initializers
│ │ ├── backtrace_silencers.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── inflections.rb
│ │ ├── mime_types.rb
│ │ ├── secret_token.rb
│ │ ├── session_store.rb
│ │ └── wrap_parameters.rb
│ ├── locales
│ │ └── en.yml
│ └── routes.rb
├── db
│ └── schema.rb
├── lib
│ └── assets
│ │ └── .gitkeep
├── log
│ └── .gitkeep
├── public
│ ├── 404.html
│ ├── 422.html
│ ├── 500.html
│ └── favicon.ico
└── script
│ └── rails
├── factories
└── messages.rb
├── functional
└── pointless_feedback
│ ├── feedback_mailer_test.rb
│ └── messages_controller_test.rb
├── generators
├── install_generator_test.rb
└── views_generator_test.rb
├── integration
└── pointless_feedback
│ ├── feedback_submission_test.rb
│ └── main_app_root_url_test.rb
├── pointless_feedback_test.rb
├── test_helper.rb
└── unit
├── helpers
└── pointless_feedback
│ └── application_helper_test.rb
└── pointless_feedback
├── captcha_test.rb
└── message_test.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | .ruby-version
2 | .bundle/
3 | log/*.log
4 | pkg/
5 | test/dummy/db/*.sqlite3
6 | test/dummy/log/*.log
7 | test/dummy/tmp/
8 | test/dummy/.sass-cache
9 | test/tmp
10 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | ruby 2.3.0
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | rvm:
3 | - 2.0.0
4 | - 2.1.0
5 | - 2.2.0
6 |
7 | gemfile:
8 | - gemfiles/rails_40.gemfile
9 | - gemfiles/rails_41.gemfile
10 | - gemfiles/rails_42.gemfile
11 |
12 | before_script:
13 | - bundle exec rake db:migrate
14 | - bundle exec rake app:db:test:prepare
15 |
16 | script: bundle exec rake
17 |
--------------------------------------------------------------------------------
/Appraisals:
--------------------------------------------------------------------------------
1 | appraise "rails-40" do
2 | gem "rails", "~> 4.0.0"
3 | end
4 |
5 | appraise "rails-41" do
6 | gem "rails", "~> 4.1.0"
7 | end
8 |
9 | appraise "rails-42" do
10 | gem "rails", "~> 4.2.0"
11 | end
12 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | # Declare your gem's dependencies in pointless_feedback.gemspec.
4 | # Bundler will treat runtime dependencies like base dependencies, and
5 | # development dependencies will be added by default to the :development group.
6 | gemspec
7 |
8 | group :test do
9 | gem 'test-unit'
10 | gem 'pry'
11 | gem 'minitest-spec-rails'
12 | gem 'mocha', require: false
13 | end
14 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | pointless_feedback (4.1.5)
5 | airrecord (~> 1.0)
6 | jquery-rails (>= 4.0)
7 | rails (>= 4.0)
8 | typhoeus (~> 0.7, >= 0.7.3)
9 |
10 | GEM
11 | remote: http://rubygems.org/
12 | specs:
13 | actionmailer (4.2.2)
14 | actionpack (= 4.2.2)
15 | actionview (= 4.2.2)
16 | activejob (= 4.2.2)
17 | mail (~> 2.5, >= 2.5.4)
18 | rails-dom-testing (~> 1.0, >= 1.0.5)
19 | actionpack (4.2.2)
20 | actionview (= 4.2.2)
21 | activesupport (= 4.2.2)
22 | rack (~> 1.6)
23 | rack-test (~> 0.6.2)
24 | rails-dom-testing (~> 1.0, >= 1.0.5)
25 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
26 | actionview (4.2.2)
27 | activesupport (= 4.2.2)
28 | builder (~> 3.1)
29 | erubis (~> 2.7.0)
30 | rails-dom-testing (~> 1.0, >= 1.0.5)
31 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
32 | activejob (4.2.2)
33 | activesupport (= 4.2.2)
34 | globalid (>= 0.3.0)
35 | activemodel (4.2.2)
36 | activesupport (= 4.2.2)
37 | builder (~> 3.1)
38 | activerecord (4.2.2)
39 | activemodel (= 4.2.2)
40 | activesupport (= 4.2.2)
41 | arel (~> 6.0)
42 | activesupport (4.2.2)
43 | i18n (~> 0.7)
44 | json (~> 1.7, >= 1.7.7)
45 | minitest (~> 5.1)
46 | thread_safe (~> 0.3, >= 0.3.4)
47 | tzinfo (~> 1.1)
48 | addressable (2.3.8)
49 | airrecord (1.0.8)
50 | faraday (>= 0.10, < 3.0)
51 | net-http-persistent
52 | appraisal (2.0.1)
53 | activesupport (>= 3.2.21)
54 | bundler
55 | rake
56 | thor (>= 0.14.0)
57 | arel (6.0.0)
58 | builder (3.2.2)
59 | capybara (2.4.4)
60 | mime-types (>= 1.16)
61 | nokogiri (>= 1.3.3)
62 | rack (>= 1.0.0)
63 | rack-test (>= 0.5.4)
64 | xpath (~> 2.0)
65 | coderay (1.1.0)
66 | connection_pool (2.2.5)
67 | erubis (2.7.0)
68 | ethon (0.15.0)
69 | ffi (>= 1.15.0)
70 | factory_girl (4.5.0)
71 | activesupport (>= 3.0.0)
72 | factory_girl_rails (4.5.0)
73 | factory_girl (~> 4.5.0)
74 | railties (>= 3.0.0)
75 | faraday (1.0.1)
76 | multipart-post (>= 1.2, < 3)
77 | ffi (1.15.5)
78 | globalid (0.3.5)
79 | activesupport (>= 4.1.0)
80 | i18n (0.7.0)
81 | jquery-rails (4.4.0)
82 | rails-dom-testing (>= 1, < 3)
83 | railties (>= 4.2.0)
84 | thor (>= 0.14, < 2.0)
85 | json (1.8.6)
86 | launchy (2.4.3)
87 | addressable (~> 2.3)
88 | loofah (2.0.2)
89 | nokogiri (>= 1.5.9)
90 | mail (2.6.3)
91 | mime-types (>= 1.16, < 3)
92 | metaclass (0.0.4)
93 | method_source (0.8.2)
94 | mime-types (2.6.1)
95 | mini_portile (0.6.2)
96 | minitest (5.7.0)
97 | minitest-spec-rails (5.2.2)
98 | minitest (~> 5.0)
99 | rails (~> 4.1)
100 | mocha (1.1.0)
101 | metaclass (~> 0.0.1)
102 | multipart-post (2.1.1)
103 | net-http-persistent (4.0.1)
104 | connection_pool (~> 2.2)
105 | nokogiri (1.6.6.2)
106 | mini_portile (~> 0.6.0)
107 | power_assert (0.2.3)
108 | pry (0.10.1)
109 | coderay (~> 1.1.0)
110 | method_source (~> 0.8.1)
111 | slop (~> 3.4)
112 | rack (1.6.4)
113 | rack-test (0.6.3)
114 | rack (>= 1.0)
115 | rails (4.2.2)
116 | actionmailer (= 4.2.2)
117 | actionpack (= 4.2.2)
118 | actionview (= 4.2.2)
119 | activejob (= 4.2.2)
120 | activemodel (= 4.2.2)
121 | activerecord (= 4.2.2)
122 | activesupport (= 4.2.2)
123 | bundler (>= 1.3.0, < 2.0)
124 | railties (= 4.2.2)
125 | sprockets-rails
126 | rails-deprecated_sanitizer (1.0.3)
127 | activesupport (>= 4.2.0.alpha)
128 | rails-dom-testing (1.0.6)
129 | activesupport (>= 4.2.0.beta, < 5.0)
130 | nokogiri (~> 1.6.0)
131 | rails-deprecated_sanitizer (>= 1.0.1)
132 | rails-html-sanitizer (1.0.2)
133 | loofah (~> 2.0)
134 | railties (4.2.2)
135 | actionpack (= 4.2.2)
136 | activesupport (= 4.2.2)
137 | rake (>= 0.8.7)
138 | thor (>= 0.18.1, < 2.0)
139 | rake (10.4.2)
140 | slop (3.6.0)
141 | sprockets (3.2.0)
142 | rack (~> 1.0)
143 | sprockets-rails (2.3.1)
144 | actionpack (>= 3.0)
145 | activesupport (>= 3.0)
146 | sprockets (>= 2.8, < 4.0)
147 | sqlite3 (1.3.10)
148 | test-unit (3.1.2)
149 | power_assert
150 | thor (0.19.1)
151 | thread_safe (0.3.5)
152 | typhoeus (0.8.0)
153 | ethon (>= 0.8.0)
154 | tzinfo (1.2.2)
155 | thread_safe (~> 0.1)
156 | xpath (2.0.0)
157 | nokogiri (~> 1.3)
158 |
159 | PLATFORMS
160 | ruby
161 |
162 | DEPENDENCIES
163 | appraisal (~> 2.0)
164 | capybara (~> 2.4)
165 | factory_girl_rails (~> 4.5)
166 | launchy (~> 2.4)
167 | minitest-spec-rails
168 | mocha
169 | pointless_feedback!
170 | pry
171 | sqlite3 (~> 1.3)
172 | test-unit
173 |
174 | BUNDLED WITH
175 | 1.17.3
176 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2013 Viget
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pointless Feedback
2 |
3 | [](https://codeclimate.com/github/vigetlabs/pointless-feedback) [](https://travis-ci.org/vigetlabs/pointless-feedback)
4 |
5 | A Rails engine that provides a platform for your app to submit user feedback to
6 | a specified service. Messages are stored in your database as a fail-safe when
7 | the specified service is unavailable. Currently, only email, Unfuddle, and
8 | Github Issues are supported.
9 |
10 | *Brought to you by the fine folks at [Viget](http://viget.com) and commissioned
11 | under [Pointless Corp](http://www.pointlesscorp.com/).*
12 |
13 | ## Contents
14 |
15 | 1. [Versions](#versions)
16 | 2. [Installation](#installation)
17 | 3. [Configuration](#configuration)
18 | 4. [Customization](#customization)
19 | 5. [Development](#development)
20 | 6. [Roadmap](#roadmap)
21 | 7. [Contributors](#contributors)
22 |
23 | ## Versions
24 |
25 | For Rails 3.x support, use Pointless Feedback version 1.x.
26 |
27 | For Rails 4.x and greater, use Pointless Feedback version 4.x.
28 |
29 | Additionally, Pointless 4.x will only support Ruby 2.x.
30 |
31 | ## Installation
32 |
33 | To install, simply add the following to your Gemfile:
34 |
35 | ```ruby
36 | gem 'pointless_feedback'
37 | ```
38 |
39 | After you install Pointless Feedback and add it to your Gemfile, you need to
40 | run the generator and install the engine migrations:
41 |
42 | ```
43 | bundle exec rails generate pointless_feedback:install
44 | bundle exec rake pointless_feedback:install:migrations
45 | bundle exec rake db:migrate
46 | ```
47 |
48 | The generator will install an initializer which describes ALL Pointless
49 | Feedback's configuration options and you MUST take a look at it. When you are
50 | done, you are ready to mount the routes in your `config/routes.rb` file.
51 |
52 | ```ruby
53 | mount PointlessFeedback::Engine, :at => '/feedback'
54 | ```
55 |
56 | Pointless Feedback uses flash messages to let users know if feedback was
57 | successfully sent. Pointless Feedback expects your application to call
58 | `flash[:notice]` as appropriate.
59 |
60 | After submitting feedback, Pointless Feedback will use your application's
61 | default `root_path`. This means that you need to set the root inside your
62 | routes:
63 |
64 | ```ruby
65 | root :to => 'home#index'
66 | ```
67 |
68 | That's it! Start your Rails server and navigate to `/feedback` to see a basic
69 | feedback form that users can submit.
70 |
71 | ## Configuration
72 |
73 | There are a number of configuration variables you can set in the initializer generated by `rails generate pointless_feedback:install`
74 |
75 | #### Email Configuration
76 |
77 | **email_feedback:**
78 | Defaults to `false`. If set to `true` will send feedback as an email.
79 |
80 | **message_topics:**
81 | Defaults to `['Error on page', 'Other']`. Populates the "Topic" dropdown for feedback submissions.
82 |
83 | **send_from_submitter:**
84 | Defaults to `false`. If set to `true` will use the submitted email address as the from address for feedback emails.
85 |
86 | **to_emails:**
87 | Specifies to what addresses feedback email is sent to.
88 |
89 | **from_email:**
90 | Specifies what address the feedback email is sent from.
91 |
92 | **table_name:**
93 | Defaults to engine's namespace, e.g. `pointless_feedback_messages`. Change to any desired table for `PointlessFeedback::Message` model.
94 |
95 | **invalid_words:**
96 | List of words in the feedback description that would prevent an email from sending.
97 |
98 | **show_url_field:**
99 | Defaults to `false`. If set to `true`, will show an additional URL field in the form.
100 |
101 | **url_label:**
102 | Defaults to `URL`. The label for the URL field that will be shown if `show_url_field` is `true`.
103 |
104 | **google_captcha_site_key & google_captcha_secret_key:**
105 | If you'd like to block out the robots, set up a Google Captcha instance:
106 |
107 | Do so here - http://www.google.com/recaptcha/admin. Be sure to configure it with the reCAPTCHA v2 `"I'm not a robot" Checkbox`. Then copy the site_key and secret_key into these config variables and PointlessFeedback will handle the rest!
108 |
109 | #### Airtable Configuration
110 |
111 | **airtable_api_key:**
112 | Self explanatory, required if you want to export submitted feedback contents into an Airtable database.
113 |
114 | **airtable_app_key:**
115 | Self explanatory
116 |
117 | **airtable_table_name:**
118 | Self explanatory
119 |
120 | ## Customization
121 |
122 | Pointless Feedback provides you with a simple setup that should cover most
123 | cases. However, certain things are customizable to suit your app's needs.
124 |
125 | #### Views
126 |
127 | Since Pointless Feedback is an engine, all its views are packaged inside the
128 | gem. These views will help you get started, but after some time you may want
129 | to change them. If this is the case, you just need to invoke the following
130 | generator, and it will copy all views to your application:
131 |
132 | ```
133 | bundle exec rails generate pointless_feedback:views
134 | ```
135 |
136 | After doing so, you will find the views at `app/views/pointless_feedback/`
137 | within your application.
138 |
139 | **Note: Any url helpers used while on the feedback form page will need to prefaced with `main_app`.**
140 |
141 | #### I18n
142 |
143 | Most of the messaging in the Pointless Feedback engine uses I18n and can be
144 | customized within your respective localization file.
145 |
146 | To customize the flash notification upon successful submission, add the
147 | following to your `config/locales/en.yml` file:
148 |
149 | ```yml
150 | pointless_feedback:
151 | messages:
152 | saved: "Thanks for your feedback!"
153 | ```
154 |
155 | The error messages output defaults to the following:
156 |
157 | ```yml
158 | activerecord:
159 | errors:
160 | header: "Invalid Fields"
161 | message: "Correct the following errors and try again."
162 | ```
163 |
164 | To customize the subject of the feedback email, add the following to your
165 | `config/locales/en.yml` file as well:
166 |
167 | ```yml
168 | pointless_feedback:
169 | email:
170 | subject: "Pointless Feedback"
171 | ```
172 |
173 | #### Controllers
174 |
175 | You can overwrite `after_message_create_path` in your `ApplicationController`
176 | to customize your redirect hook.
177 |
178 | ## Development
179 |
180 | 1. Clone the repo: `git clone git://github.com/vigetlabs/pointless-feedback.git`
181 | 2. Install dependencies: `bundle install`
182 | 3. Setup databases: `bundle exec rake db:migrate && rake app:db:test:prepare`
183 | 4. Run the test suite: `bundle exec rake test`
184 | 5. Make your changes in a feature branch
185 | 6. Make sure the test suite passes before submitting a Pull Request
186 |
187 | ## Roadmap
188 |
189 | - [ ] Add service to send to Github
190 | - [ ] Add admin view for messages with comments
191 |
192 | ## Contributors
193 |
194 | * [@zporter](http://github.com/zporter)
195 | * [@efatsi](http://github.com/efatsi)
196 | * [@reagent](http://github.com/reagent)
197 |
198 | This project rocks and uses MIT-LICENSE.
199 |
200 | ***
201 |
202 |
203 |
204 |
205 |
206 | Visit [code.viget.com](http://code.viget.com) to see more projects from [Viget.](https://viget.com)
207 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | begin
3 | require 'bundler/setup'
4 | rescue LoadError
5 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6 | end
7 | begin
8 | require 'rdoc/task'
9 | rescue LoadError
10 | require 'rdoc/rdoc'
11 | require 'rake/rdoctask'
12 | RDoc::Task = Rake::RDocTask
13 | end
14 |
15 | RDoc::Task.new(:rdoc) do |rdoc|
16 | rdoc.rdoc_dir = 'rdoc'
17 | rdoc.title = 'PointlessFeedback'
18 | rdoc.options << '--line-numbers'
19 | rdoc.rdoc_files.include('README.rdoc')
20 | rdoc.rdoc_files.include('lib/**/*.rb')
21 | end
22 |
23 | APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24 | load 'rails/tasks/engine.rake'
25 |
26 |
27 |
28 | Bundler::GemHelper.install_tasks
29 |
30 | require 'rake/testtask'
31 |
32 | Rake::TestTask.new(:test) do |t|
33 | t.libs << 'lib'
34 | t.libs << 'test'
35 | t.pattern = 'test/**/*_test.rb'
36 | t.verbose = false
37 | end
38 |
39 |
40 | task :default => :test
41 |
--------------------------------------------------------------------------------
/app/assets/images/pointless_feedback/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vigetlabs/pointless-feedback/9b3363237b316e5fe0511c86624f71c3235f7ded/app/assets/images/pointless_feedback/.gitkeep
--------------------------------------------------------------------------------
/app/assets/javascripts/pointless_feedback/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // the compiled file.
9 | //
10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11 | // GO AFTER THE REQUIRES BELOW.
12 | //
13 | //= require jquery
14 | //= require jquery_ujs
15 | //= require_tree .
16 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/pointless_feedback/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the top of the
9 | * compiled file, but it's generally better to create a new file per style scope.
10 | *
11 | *= require_self
12 | *= require_tree .
13 | */
14 |
--------------------------------------------------------------------------------
/app/controllers/pointless_feedback/messages_controller.rb:
--------------------------------------------------------------------------------
1 | module PointlessFeedback
2 | class MessagesController < PointlessFeedback.parent_controller.constantize
3 | helper PointlessFeedback::ApplicationHelper
4 |
5 | def new
6 | @message = Message.new
7 | end
8 |
9 | def create
10 | @message = Message.new(message_params)
11 |
12 | if pass_captcha? && @message.save
13 | flash[:notice] = I18n.t('pointless_feedback.messages.saved',
14 | :default => 'Thanks for your feedback!')
15 |
16 | redirect_to after_message_create_path
17 | else
18 | flash[:alert] = I18n.t('pointless_feedback.messages.invalid_captcha',
19 | :default => 'Are you a robot? Please check the box at the bottom of the page and try again.')
20 | render :new
21 | end
22 | end
23 |
24 | private
25 |
26 | def message_params
27 | params.require(:message).permit([
28 | :description,
29 | :email_address,
30 | :name,
31 | :topic,
32 | :contact_info,
33 | :url
34 | ])
35 | end
36 |
37 | def pass_captcha?
38 | if PointlessFeedback.using_captcha?
39 | PointlessFeedback::Captcha.pass?(params["g-recaptcha-response"])
40 | else
41 | true
42 | end
43 | end
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/app/helpers/pointless_feedback/application_helper.rb:
--------------------------------------------------------------------------------
1 | module PointlessFeedback
2 | module ApplicationHelper
3 | delegate :root_url, :root_path, :to => :main_app
4 |
5 | # Can search for named routes directly in the main app, omitting
6 | # the "main_app." prefix
7 | def method_missing(method, *args, &block)
8 | if main_app_url_helper?(method)
9 | main_app.send(method, *args)
10 | else
11 | super
12 | end
13 | end
14 |
15 | def respond_to_missing?(method, include_all)
16 | main_app_url_helper?(method) || super
17 | end
18 |
19 |
20 | private
21 |
22 | def main_app_url_helper?(method)
23 | /\A\w+(_path|_url)\z/ === method.to_s && main_app.respond_to?(method)
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/app/mailers/pointless_feedback/feedback_mailer.rb:
--------------------------------------------------------------------------------
1 | module PointlessFeedback
2 | class FeedbackMailer < ActionMailer::Base
3 | def feedback(message)
4 | @message = message
5 |
6 | mail(:to => to_emails, :subject => feedback_subject, :from => from_address)
7 | end
8 |
9 | private
10 |
11 | def from_address
12 | if PointlessFeedback.send_from_submitter
13 | @message.email_address
14 | else
15 | PointlessFeedback.from_email
16 | end
17 | end
18 |
19 | def to_emails
20 | Array(PointlessFeedback.to_emails)
21 | end
22 |
23 | def feedback_subject
24 | I18n.t('pointless_feedback.email.subject', :default => 'Feedback')
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/app/models/pointless_feedback/message.rb:
--------------------------------------------------------------------------------
1 | module PointlessFeedback
2 | class Message < ActiveRecord::Base
3 | if PointlessFeedback.table_name.present?
4 | self.table_name = PointlessFeedback.table_name
5 | end
6 |
7 | attr_accessor :contact_info
8 |
9 | validates :name, :email_address, :topic, :description, :presence => true
10 | validates :topic, :inclusion => PointlessFeedback.message_topics
11 | validates :email_address, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
12 | validate :is_not_spam
13 |
14 | after_save :export_feedback, :unless => :ignore_feedback?
15 |
16 | private
17 |
18 | def export_feedback
19 | if PointlessFeedback.email_feedback
20 | # Support Rails < 4.2 and >= 4.2 delivery options
21 | mailer = FeedbackMailer.feedback(self)
22 | mailer.respond_to?(:deliver_now) ? mailer.deliver_now : mailer.deliver
23 | end
24 |
25 | if PointlessFeedback.airtable_api_key
26 | feedback_table = Airrecord.table(
27 | PointlessFeedback.airtable_api_key,
28 | PointlessFeedback.airtable_app_key,
29 | PointlessFeedback.airtable_table_name
30 | )
31 |
32 | begin
33 | feedback_table.create(
34 | "Name" => name,
35 | "Email" => email_address,
36 | "Topic" => topic,
37 | "Description" => description,
38 | "Date" => created_at.strftime("%m/%d/%y"),
39 | "URL" => url
40 | )
41 | rescue => e
42 | # ignore errors in production, last thing you want is a 500
43 | # when someone's trying to complain about your site.
44 | raise(e) if Rails.env.development?
45 | end
46 | end
47 | end
48 |
49 | def ignore_feedback?
50 | honeypot_filled_in? || contains_invalid_words?
51 | end
52 |
53 | def honeypot_filled_in?
54 | contact_info.present?
55 | end
56 |
57 | def contains_invalid_words?
58 | PointlessFeedback.invalid_words.each do |word|
59 | if description.downcase.include? word.downcase
60 | return true
61 | end
62 | end
63 |
64 | false
65 | end
66 |
67 | def is_not_spam
68 | if URI.extract(description || "").count >= 3
69 | errors.add(:description, "can not contain more than 2 http links (often a sign of spam)")
70 | end
71 | end
72 | end
73 | end
74 |
--------------------------------------------------------------------------------
/app/views/layouts/pointless_feedback/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Name: <%= @message.name %>
4 |Email Address: <%= @message.email_address %>
5 |Topic: <%= @message.topic %>
6 | <% if PointlessFeedback.show_url_field %> 7 |<%= PointlessFeedback.url_label %>: <%= @message.url %>
8 | <% end %> 9 |Description: <%= @message.description %>
10 | -------------------------------------------------------------------------------- /app/views/pointless_feedback/messages/new.html.erb: -------------------------------------------------------------------------------- 1 | <% if PointlessFeedback.using_captcha? %> 2 | 3 | 4 | 5 | <% end %> 6 | 7 | <%= form_for @message do |f| %> 8 | <% if @message.errors.any? %> 9 | 24 | <% end %> 25 | 26 | 39 | 40 | 68 | 69 | <% if PointlessFeedback.using_captcha? %> 70 | 71 | <% end %> 72 | 73 | <%= f.submit 'Submit' %> 74 | <% end %> 75 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | PointlessFeedback::Engine.routes.draw do 2 | root :to => 'messages#new' 3 | 4 | resources :messages, :only => [:new, :create] 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20130501182659_create_pointless_feedback_messages.rb: -------------------------------------------------------------------------------- 1 | class CreatePointlessFeedbackMessages < ActiveRecord::Migration 2 | def change 3 | create_table :pointless_feedback_messages do |t| 4 | t.string :name 5 | t.string :email_address 6 | t.string :topic 7 | t.text :description 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20220518205500_add_url_to_pointless_feedback_messages.rb: -------------------------------------------------------------------------------- 1 | class AddUrlToPointlessFeedbackMessages < ActiveRecord::Migration 2 | def change 3 | add_column :pointless_feedback_messages, :url, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /gemfiles/rails_40.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "jquery-rails" 6 | gem "rails", "~> 4.0.0" 7 | 8 | group :test do 9 | gem "test-unit" 10 | gem "pry" 11 | gem "minitest-spec-rails" 12 | gem "mocha", :require => false 13 | end 14 | 15 | gemspec :path => "../" 16 | -------------------------------------------------------------------------------- /gemfiles/rails_40.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | pointless_feedback (4.0.0) 5 | rails (~> 4.0) 6 | 7 | GEM 8 | remote: http://rubygems.org/ 9 | specs: 10 | actionmailer (4.0.13) 11 | actionpack (= 4.0.13) 12 | mail (~> 2.5, >= 2.5.4) 13 | actionpack (4.0.13) 14 | activesupport (= 4.0.13) 15 | builder (~> 3.1.0) 16 | erubis (~> 2.7.0) 17 | rack (~> 1.5.2) 18 | rack-test (~> 0.6.2) 19 | activemodel (4.0.13) 20 | activesupport (= 4.0.13) 21 | builder (~> 3.1.0) 22 | activerecord (4.0.13) 23 | activemodel (= 4.0.13) 24 | activerecord-deprecated_finders (~> 1.0.2) 25 | activesupport (= 4.0.13) 26 | arel (~> 4.0.0) 27 | activerecord-deprecated_finders (1.0.4) 28 | activesupport (4.0.13) 29 | i18n (~> 0.6, >= 0.6.9) 30 | minitest (~> 4.2) 31 | multi_json (~> 1.3) 32 | thread_safe (~> 0.1) 33 | tzinfo (~> 0.3.37) 34 | addressable (2.3.8) 35 | appraisal (2.0.1) 36 | activesupport (>= 3.2.21) 37 | bundler 38 | rake 39 | thor (>= 0.14.0) 40 | arel (4.0.2) 41 | builder (3.1.4) 42 | capybara (2.4.4) 43 | mime-types (>= 1.16) 44 | nokogiri (>= 1.3.3) 45 | rack (>= 1.0.0) 46 | rack-test (>= 0.5.4) 47 | xpath (~> 2.0) 48 | coderay (1.1.0) 49 | erubis (2.7.0) 50 | factory_girl (4.5.0) 51 | activesupport (>= 3.0.0) 52 | factory_girl_rails (4.5.0) 53 | factory_girl (~> 4.5.0) 54 | railties (>= 3.0.0) 55 | i18n (0.7.0) 56 | jquery-rails (3.0.4) 57 | railties (>= 3.0, < 5.0) 58 | thor (>= 0.14, < 2.0) 59 | launchy (2.4.3) 60 | addressable (~> 2.3) 61 | mail (2.6.3) 62 | mime-types (>= 1.16, < 3) 63 | metaclass (0.0.4) 64 | method_source (0.8.2) 65 | mime-types (2.6.1) 66 | mini_portile (0.6.2) 67 | minitest (4.7.5) 68 | minitest-spec-rails (4.7.2) 69 | minitest (~> 4.7) 70 | rails (>= 3.0) 71 | mocha (1.1.0) 72 | metaclass (~> 0.0.1) 73 | multi_json (1.11.1) 74 | nokogiri (1.6.6.2) 75 | mini_portile (~> 0.6.0) 76 | power_assert (0.2.2) 77 | pry (0.10.1) 78 | coderay (~> 1.1.0) 79 | method_source (~> 0.8.1) 80 | slop (~> 3.4) 81 | rack (1.5.5) 82 | rack-test (0.6.3) 83 | rack (>= 1.0) 84 | rails (4.0.13) 85 | actionmailer (= 4.0.13) 86 | actionpack (= 4.0.13) 87 | activerecord (= 4.0.13) 88 | activesupport (= 4.0.13) 89 | bundler (>= 1.3.0, < 2.0) 90 | railties (= 4.0.13) 91 | sprockets-rails (~> 2.0) 92 | railties (4.0.13) 93 | actionpack (= 4.0.13) 94 | activesupport (= 4.0.13) 95 | rake (>= 0.8.7) 96 | thor (>= 0.18.1, < 2.0) 97 | rake (10.4.2) 98 | slop (3.6.0) 99 | sprockets (3.2.0) 100 | rack (~> 1.0) 101 | sprockets-rails (2.3.1) 102 | actionpack (>= 3.0) 103 | activesupport (>= 3.0) 104 | sprockets (>= 2.8, < 4.0) 105 | sqlite3 (1.3.10) 106 | test-unit (3.0.8) 107 | power_assert 108 | thor (0.19.1) 109 | thread_safe (0.3.5) 110 | tzinfo (0.3.44) 111 | xpath (2.0.0) 112 | nokogiri (~> 1.3) 113 | 114 | PLATFORMS 115 | ruby 116 | 117 | DEPENDENCIES 118 | appraisal 119 | capybara 120 | factory_girl_rails 121 | jquery-rails 122 | launchy 123 | minitest-spec-rails 124 | mocha 125 | pointless_feedback! 126 | pry 127 | rails (~> 4.0.0) 128 | sqlite3 129 | test-unit 130 | -------------------------------------------------------------------------------- /gemfiles/rails_41.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "jquery-rails" 6 | gem "rails", "~> 4.1.0" 7 | 8 | group :test do 9 | gem "test-unit" 10 | gem "pry" 11 | gem "minitest-spec-rails" 12 | gem "mocha", :require => false 13 | end 14 | 15 | gemspec :path => "../" 16 | -------------------------------------------------------------------------------- /gemfiles/rails_41.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | pointless_feedback (4.0.0) 5 | rails (~> 4.0) 6 | 7 | GEM 8 | remote: http://rubygems.org/ 9 | specs: 10 | actionmailer (4.1.11) 11 | actionpack (= 4.1.11) 12 | actionview (= 4.1.11) 13 | mail (~> 2.5, >= 2.5.4) 14 | actionpack (4.1.11) 15 | actionview (= 4.1.11) 16 | activesupport (= 4.1.11) 17 | rack (~> 1.5.2) 18 | rack-test (~> 0.6.2) 19 | actionview (4.1.11) 20 | activesupport (= 4.1.11) 21 | builder (~> 3.1) 22 | erubis (~> 2.7.0) 23 | activemodel (4.1.11) 24 | activesupport (= 4.1.11) 25 | builder (~> 3.1) 26 | activerecord (4.1.11) 27 | activemodel (= 4.1.11) 28 | activesupport (= 4.1.11) 29 | arel (~> 5.0.0) 30 | activesupport (4.1.11) 31 | i18n (~> 0.6, >= 0.6.9) 32 | json (~> 1.7, >= 1.7.7) 33 | minitest (~> 5.1) 34 | thread_safe (~> 0.1) 35 | tzinfo (~> 1.1) 36 | addressable (2.3.8) 37 | appraisal (2.0.1) 38 | activesupport (>= 3.2.21) 39 | bundler 40 | rake 41 | thor (>= 0.14.0) 42 | arel (5.0.1.20140414130214) 43 | builder (3.2.2) 44 | capybara (2.4.4) 45 | mime-types (>= 1.16) 46 | nokogiri (>= 1.3.3) 47 | rack (>= 1.0.0) 48 | rack-test (>= 0.5.4) 49 | xpath (~> 2.0) 50 | coderay (1.1.0) 51 | erubis (2.7.0) 52 | factory_girl (4.5.0) 53 | activesupport (>= 3.0.0) 54 | factory_girl_rails (4.5.0) 55 | factory_girl (~> 4.5.0) 56 | railties (>= 3.0.0) 57 | i18n (0.7.0) 58 | jquery-rails (3.1.3) 59 | railties (>= 3.0, < 5.0) 60 | thor (>= 0.14, < 2.0) 61 | json (1.8.3) 62 | launchy (2.4.3) 63 | addressable (~> 2.3) 64 | mail (2.6.3) 65 | mime-types (>= 1.16, < 3) 66 | metaclass (0.0.4) 67 | method_source (0.8.2) 68 | mime-types (2.6.1) 69 | mini_portile (0.6.2) 70 | minitest (5.7.0) 71 | minitest-spec-rails (5.2.2) 72 | minitest (~> 5.0) 73 | rails (~> 4.1) 74 | mocha (1.1.0) 75 | metaclass (~> 0.0.1) 76 | nokogiri (1.6.6.2) 77 | mini_portile (~> 0.6.0) 78 | power_assert (0.2.3) 79 | pry (0.10.1) 80 | coderay (~> 1.1.0) 81 | method_source (~> 0.8.1) 82 | slop (~> 3.4) 83 | rack (1.5.5) 84 | rack-test (0.6.3) 85 | rack (>= 1.0) 86 | rails (4.1.11) 87 | actionmailer (= 4.1.11) 88 | actionpack (= 4.1.11) 89 | actionview (= 4.1.11) 90 | activemodel (= 4.1.11) 91 | activerecord (= 4.1.11) 92 | activesupport (= 4.1.11) 93 | bundler (>= 1.3.0, < 2.0) 94 | railties (= 4.1.11) 95 | sprockets-rails (~> 2.0) 96 | railties (4.1.11) 97 | actionpack (= 4.1.11) 98 | activesupport (= 4.1.11) 99 | rake (>= 0.8.7) 100 | thor (>= 0.18.1, < 2.0) 101 | rake (10.4.2) 102 | slop (3.6.0) 103 | sprockets (3.2.0) 104 | rack (~> 1.0) 105 | sprockets-rails (2.3.1) 106 | actionpack (>= 3.0) 107 | activesupport (>= 3.0) 108 | sprockets (>= 2.8, < 4.0) 109 | sqlite3 (1.3.10) 110 | test-unit (3.1.2) 111 | power_assert 112 | thor (0.19.1) 113 | thread_safe (0.3.5) 114 | tzinfo (1.2.2) 115 | thread_safe (~> 0.1) 116 | xpath (2.0.0) 117 | nokogiri (~> 1.3) 118 | 119 | PLATFORMS 120 | ruby 121 | 122 | DEPENDENCIES 123 | appraisal 124 | capybara 125 | factory_girl_rails 126 | jquery-rails 127 | launchy 128 | minitest-spec-rails 129 | mocha 130 | pointless_feedback! 131 | pry 132 | rails (~> 4.1.0) 133 | sqlite3 134 | test-unit 135 | -------------------------------------------------------------------------------- /gemfiles/rails_42.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "jquery-rails" 6 | gem "rails", "~> 4.2.0" 7 | 8 | group :test do 9 | gem "test-unit" 10 | gem "pry" 11 | gem "minitest-spec-rails" 12 | gem "mocha", :require => false 13 | end 14 | 15 | gemspec :path => "../" 16 | -------------------------------------------------------------------------------- /gemfiles/rails_42.gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | pointless_feedback (4.0.0) 5 | rails (~> 4.0) 6 | 7 | GEM 8 | remote: http://rubygems.org/ 9 | specs: 10 | actionmailer (4.2.2) 11 | actionpack (= 4.2.2) 12 | actionview (= 4.2.2) 13 | activejob (= 4.2.2) 14 | mail (~> 2.5, >= 2.5.4) 15 | rails-dom-testing (~> 1.0, >= 1.0.5) 16 | actionpack (4.2.2) 17 | actionview (= 4.2.2) 18 | activesupport (= 4.2.2) 19 | rack (~> 1.6) 20 | rack-test (~> 0.6.2) 21 | rails-dom-testing (~> 1.0, >= 1.0.5) 22 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 23 | actionview (4.2.2) 24 | activesupport (= 4.2.2) 25 | builder (~> 3.1) 26 | erubis (~> 2.7.0) 27 | rails-dom-testing (~> 1.0, >= 1.0.5) 28 | rails-html-sanitizer (~> 1.0, >= 1.0.1) 29 | activejob (4.2.2) 30 | activesupport (= 4.2.2) 31 | globalid (>= 0.3.0) 32 | activemodel (4.2.2) 33 | activesupport (= 4.2.2) 34 | builder (~> 3.1) 35 | activerecord (4.2.2) 36 | activemodel (= 4.2.2) 37 | activesupport (= 4.2.2) 38 | arel (~> 6.0) 39 | activesupport (4.2.2) 40 | i18n (~> 0.7) 41 | json (~> 1.7, >= 1.7.7) 42 | minitest (~> 5.1) 43 | thread_safe (~> 0.3, >= 0.3.4) 44 | tzinfo (~> 1.1) 45 | addressable (2.3.8) 46 | appraisal (2.0.1) 47 | activesupport (>= 3.2.21) 48 | bundler 49 | rake 50 | thor (>= 0.14.0) 51 | arel (6.0.0) 52 | builder (3.2.2) 53 | capybara (2.4.4) 54 | mime-types (>= 1.16) 55 | nokogiri (>= 1.3.3) 56 | rack (>= 1.0.0) 57 | rack-test (>= 0.5.4) 58 | xpath (~> 2.0) 59 | coderay (1.1.0) 60 | erubis (2.7.0) 61 | factory_girl (4.5.0) 62 | activesupport (>= 3.0.0) 63 | factory_girl_rails (4.5.0) 64 | factory_girl (~> 4.5.0) 65 | railties (>= 3.0.0) 66 | globalid (0.3.5) 67 | activesupport (>= 4.1.0) 68 | i18n (0.7.0) 69 | jquery-rails (4.0.4) 70 | rails-dom-testing (~> 1.0) 71 | railties (>= 4.2.0) 72 | thor (>= 0.14, < 2.0) 73 | json (1.8.3) 74 | launchy (2.4.3) 75 | addressable (~> 2.3) 76 | loofah (2.0.2) 77 | nokogiri (>= 1.5.9) 78 | mail (2.6.3) 79 | mime-types (>= 1.16, < 3) 80 | metaclass (0.0.4) 81 | method_source (0.8.2) 82 | mime-types (2.6.1) 83 | mini_portile (0.6.2) 84 | minitest (5.7.0) 85 | minitest-spec-rails (5.2.2) 86 | minitest (~> 5.0) 87 | rails (~> 4.1) 88 | mocha (1.1.0) 89 | metaclass (~> 0.0.1) 90 | nokogiri (1.6.6.2) 91 | mini_portile (~> 0.6.0) 92 | power_assert (0.2.3) 93 | pry (0.10.1) 94 | coderay (~> 1.1.0) 95 | method_source (~> 0.8.1) 96 | slop (~> 3.4) 97 | rack (1.6.4) 98 | rack-test (0.6.3) 99 | rack (>= 1.0) 100 | rails (4.2.2) 101 | actionmailer (= 4.2.2) 102 | actionpack (= 4.2.2) 103 | actionview (= 4.2.2) 104 | activejob (= 4.2.2) 105 | activemodel (= 4.2.2) 106 | activerecord (= 4.2.2) 107 | activesupport (= 4.2.2) 108 | bundler (>= 1.3.0, < 2.0) 109 | railties (= 4.2.2) 110 | sprockets-rails 111 | rails-deprecated_sanitizer (1.0.3) 112 | activesupport (>= 4.2.0.alpha) 113 | rails-dom-testing (1.0.6) 114 | activesupport (>= 4.2.0.beta, < 5.0) 115 | nokogiri (~> 1.6.0) 116 | rails-deprecated_sanitizer (>= 1.0.1) 117 | rails-html-sanitizer (1.0.2) 118 | loofah (~> 2.0) 119 | railties (4.2.2) 120 | actionpack (= 4.2.2) 121 | activesupport (= 4.2.2) 122 | rake (>= 0.8.7) 123 | thor (>= 0.18.1, < 2.0) 124 | rake (10.4.2) 125 | slop (3.6.0) 126 | sprockets (3.2.0) 127 | rack (~> 1.0) 128 | sprockets-rails (2.3.1) 129 | actionpack (>= 3.0) 130 | activesupport (>= 3.0) 131 | sprockets (>= 2.8, < 4.0) 132 | sqlite3 (1.3.10) 133 | test-unit (3.1.2) 134 | power_assert 135 | thor (0.19.1) 136 | thread_safe (0.3.5) 137 | tzinfo (1.2.2) 138 | thread_safe (~> 0.1) 139 | xpath (2.0.0) 140 | nokogiri (~> 1.3) 141 | 142 | PLATFORMS 143 | ruby 144 | 145 | DEPENDENCIES 146 | appraisal 147 | capybara 148 | factory_girl_rails 149 | jquery-rails 150 | launchy 151 | minitest-spec-rails 152 | mocha 153 | pointless_feedback! 154 | pry 155 | rails (~> 4.2.0) 156 | sqlite3 157 | test-unit 158 | -------------------------------------------------------------------------------- /lib/generators/pointless_feedback/install_generator.rb: -------------------------------------------------------------------------------- 1 | module PointlessFeedback 2 | module Generators 3 | class InstallGenerator < Rails::Generators::Base 4 | source_root File.expand_path("../../templates", __FILE__) 5 | 6 | desc "Creates a PointlessFeedback initializer for your application." 7 | 8 | def copy_initializer 9 | template "pointless_feedback.rb", "config/initializers/pointless_feedback.rb" 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/generators/pointless_feedback/views_generator.rb: -------------------------------------------------------------------------------- 1 | module PointlessFeedback 2 | module Generators 3 | class ViewsGenerator < Rails::Generators::Base 4 | desc "Copies Pointless Feedback views to your application." 5 | source_root File.expand_path("../../../../app/views/pointless_feedback", __FILE__) 6 | 7 | public_task :copy_views 8 | 9 | def copy_views 10 | directory 'messages', 'app/views/pointless_feedback/messages' do |content| 11 | content 12 | end 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/generators/templates/pointless_feedback.rb: -------------------------------------------------------------------------------- 1 | PointlessFeedback.setup do |config| 2 | # ==> Feedback Configuration 3 | # Configure the topics for the user to choose from on the feedback form 4 | # config.message_topics = ['Error on page', 'Feature Request', 'Praise', 'Other'] 5 | 6 | # ==> Email Configuration 7 | # Configure feedback email properties (disabled by default) 8 | # Variables needed for emailing feedback 9 | # config.email_feedback = false 10 | # config.send_from_submitter = false 11 | # config.from_email = 'feedback@pointlesscorp.com' 12 | # config.to_emails = ['first@example.com', 'second@example.com'] 13 | 14 | # ==> Google reCAPTCHA Configuration 15 | # If you'd like to enable Google reCAPTCHA, 16 | # 1. Register your site at: https://www.google.com/recaptcha/admin 17 | # 2. !! Ensure you opt for reCAPTCHA v2. Support for v3 is not here yet. 18 | # 3. Grab the site and secret key and paste them here. 19 | # 20 | # config.google_captcha_site_key = nil 21 | # config.google_captcha_secret_key = nil 22 | 23 | # ==> Airtable Configuration 24 | # If you'd like to export feedback submissions to an Airtable database, 25 | # 1. Create an Airtable database with the following columns: 26 | # - Name 27 | # - Email 28 | # - Topic 29 | # - Description 30 | # 2. Generate an API Key: https://airtable.com/account 31 | # 3. Find your app key and table name: https://airtable.com/api 32 | # 4. Fill in all these configs 33 | # 34 | # config.airtable_api_key = "key--------------" 35 | # config.airtable_app_key = "app--------------" 36 | # config.airtable_table_name = "Feedback Tracker" 37 | end 38 | -------------------------------------------------------------------------------- /lib/pointless_feedback.rb: -------------------------------------------------------------------------------- 1 | require "pointless_feedback/engine" 2 | require "pointless_feedback/captcha" 3 | require "typhoeus" 4 | require "jquery-rails" 5 | require "airrecord" 6 | 7 | module PointlessFeedback 8 | module Controllers 9 | autoload :Helpers, 'pointless_feedback/controllers/helpers' 10 | end 11 | 12 | # The parent controller all PointlessFeedback controllers inherit from. 13 | # Defaults to ApplicationController. This should be set early 14 | # in the initialization process and should be set to a string. 15 | mattr_accessor :parent_controller 16 | @@parent_controller = "ApplicationController" 17 | 18 | # The table name that will be used to store all messages. By default this 19 | # includes the engine's namespace (e.g. `pointless_feedback_messages`), but 20 | # it can be configured to whatever is desired. 21 | mattr_accessor :table_name 22 | 23 | # Custom topics to display on message form 24 | mattr_accessor :message_topics 25 | @@message_topics = ['Error on page', 'Other'] 26 | 27 | # Variables needed for emailing feedback 28 | mattr_accessor :email_feedback 29 | @@email_feedback = false 30 | 31 | mattr_accessor :from_email 32 | @@from_email = 'feedback@pointlesscorp.com' 33 | 34 | mattr_accessor :send_from_submitter 35 | @@send_from_submitter = false 36 | 37 | mattr_accessor :to_emails 38 | @@to_emails = ['first@example.com', 'second@example.com'] 39 | 40 | mattr_accessor :google_captcha_site_key 41 | @@google_captcha_site_key = nil 42 | 43 | mattr_accessor :google_captcha_secret_key 44 | @@google_captcha_secret_key = nil 45 | 46 | mattr_accessor :airtable_api_key 47 | @@airtable_api_key = nil 48 | 49 | mattr_accessor :airtable_app_key 50 | @@airtable_app_key = nil 51 | 52 | mattr_accessor :airtable_table_name 53 | @@airtable_table_name = nil 54 | 55 | mattr_accessor :invalid_words 56 | @@invalid_words = [] 57 | 58 | mattr_accessor :show_url_field 59 | @@show_url_field = false 60 | 61 | mattr_accessor :url_label 62 | @@url_label = "URL" 63 | 64 | # Default way to setup PointlessFeedback. Run rails generate 65 | # pointless_feedback_install to create a fresh initializer with all 66 | # configuration values. 67 | def self.setup 68 | yield self 69 | end 70 | 71 | def self.using_captcha? 72 | @@google_captcha_site_key.present? && @@google_captcha_secret_key.present? 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /lib/pointless_feedback/captcha.rb: -------------------------------------------------------------------------------- 1 | require 'uri' 2 | require 'net/http' 3 | require 'json' 4 | 5 | module PointlessFeedback 6 | class Captcha 7 | def self.pass?(captcha_response) 8 | new(captcha_response).pass? 9 | end 10 | 11 | def initialize(captcha_response) 12 | @captcha_response = captcha_response 13 | end 14 | 15 | def pass? 16 | JSON.parse(response.body)["success"] == true 17 | end 18 | 19 | private 20 | 21 | def response 22 | @response ||= Typhoeus.post(url, body: body) 23 | end 24 | 25 | def url 26 | "https://www.google.com/recaptcha/api/siteverify" 27 | end 28 | 29 | def body 30 | { 31 | secret: PointlessFeedback.google_captcha_secret_key, 32 | response: @captcha_response 33 | } 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/pointless_feedback/controllers/helpers.rb: -------------------------------------------------------------------------------- 1 | module PointlessFeedback 2 | module Controllers 3 | # Those helpers are convenience methods added to ApplicationController. 4 | module Helpers 5 | def after_message_create_path 6 | main_app.try(:root_path) || '/' 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/pointless_feedback/engine.rb: -------------------------------------------------------------------------------- 1 | module PointlessFeedback 2 | class Engine < ::Rails::Engine 3 | isolate_namespace PointlessFeedback 4 | 5 | initializer "pointless_feedback.controller.helpers" do 6 | ActiveSupport.on_load(:action_controller) do 7 | if defined?(PointlessFeedback::Controllers::Helpers) 8 | include PointlessFeedback::Controllers::Helpers 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/pointless_feedback/version.rb: -------------------------------------------------------------------------------- 1 | module PointlessFeedback 2 | VERSION = "4.1.5" 3 | end 4 | -------------------------------------------------------------------------------- /lib/tasks/pointless_feedback_tasks.rake: -------------------------------------------------------------------------------- 1 | # desc "Explaining what the task does" 2 | # task :pointless_feedback do 3 | # # Task goes here 4 | # end 5 | -------------------------------------------------------------------------------- /pointless_feedback.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | 3 | # Maintain your gem's version: 4 | require "pointless_feedback/version" 5 | 6 | # Describe your gem and declare its dependencies: 7 | Gem::Specification.new do |s| 8 | s.name = "pointless_feedback" 9 | s.version = PointlessFeedback::VERSION 10 | s.authors = ["Zachary Porter"] 11 | s.email = ["developers@viget.com"] 12 | s.homepage = "https://github.com/vigetlabs/pointless-feedback" 13 | s.summary = "Simple Rails Engine to allow users to submit feedback" 14 | s.description = "Drop in feedback engine with customizable fields, and captcha available" 15 | s.license = "MIT" 16 | 17 | s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.md"] 18 | s.test_files = Dir["test/**/*"] 19 | 20 | s.add_dependency "rails", ">= 4.0" 21 | s.add_dependency "typhoeus", "~> 0.7", ">= 0.7.3" 22 | s.add_dependency "jquery-rails", ">= 4.0" 23 | s.add_dependency "airrecord", "~> 1.0" 24 | 25 | s.add_development_dependency "sqlite3", "~> 1.3" 26 | s.add_development_dependency "capybara", "~> 2.4" 27 | s.add_development_dependency "factory_girl_rails", "~> 4.5" 28 | s.add_development_dependency "launchy", "~> 2.4" 29 | s.add_development_dependency "appraisal", "~> 2.0" 30 | end 31 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | ENGINE_ROOT = File.expand_path('../..', __FILE__) 5 | ENGINE_PATH = File.expand_path('../../lib/pointless_feedback/engine', __FILE__) 6 | 7 | require 'rails/all' 8 | require 'rails/engine/commands' 9 | -------------------------------------------------------------------------------- /test/dummy/README.rdoc: -------------------------------------------------------------------------------- 1 | == Welcome to Rails 2 | 3 | Rails is a web-application framework that includes everything needed to create 4 | database-backed web applications according to the Model-View-Control pattern. 5 | 6 | This pattern splits the view (also called the presentation) into "dumb" 7 | templates that are primarily responsible for inserting pre-built data in between 8 | HTML tags. The model contains the "smart" domain objects (such as Account, 9 | Product, Person, Post) that holds all the business logic and knows how to 10 | persist themselves to a database. The controller handles the incoming requests 11 | (such as Save New Account, Update Product, Show Post) by manipulating the model 12 | and directing data to the view. 13 | 14 | In Rails, the model is handled by what's called an object-relational mapping 15 | layer entitled Active Record. This layer allows you to present the data from 16 | database rows as objects and embellish these data objects with business logic 17 | methods. You can read more about Active Record in 18 | link:files/vendor/rails/activerecord/README.html. 19 | 20 | The controller and view are handled by the Action Pack, which handles both 21 | layers by its two parts: Action View and Action Controller. These two layers 22 | are bundled in a single package due to their heavy interdependence. This is 23 | unlike the relationship between the Active Record and Action Pack that is much 24 | more separate. Each of these packages can be used independently outside of 25 | Rails. You can read more about Action Pack in 26 | link:files/vendor/rails/actionpack/README.html. 27 | 28 | 29 | == Getting Started 30 | 31 | 1. At the command prompt, create a new Rails application: 32 | rails new myapp (where myapp is the application name) 33 | 34 | 2. Change directory to myapp and start the web server: 35 | cd myapp; rails server (run with --help for options) 36 | 37 | 3. Go to http://localhost:3000/ and you'll see: 38 | "Welcome aboard: You're riding Ruby on Rails!" 39 | 40 | 4. Follow the guidelines to start developing your application. You can find 41 | the following resources handy: 42 | 43 | * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html 44 | * Ruby on Rails Tutorial Book: http://www.railstutorial.org/ 45 | 46 | 47 | == Debugging Rails 48 | 49 | Sometimes your application goes wrong. Fortunately there are a lot of tools that 50 | will help you debug it and get it back on the rails. 51 | 52 | First area to check is the application log files. Have "tail -f" commands 53 | running on the server.log and development.log. Rails will automatically display 54 | debugging and runtime information to these files. Debugging info will also be 55 | shown in the browser on requests from 127.0.0.1. 56 | 57 | You can also log your own messages directly into the log file from your code 58 | using the Ruby logger class from inside your controllers. Example: 59 | 60 | class WeblogController < ActionController::Base 61 | def destroy 62 | @weblog = Weblog.find(params[:id]) 63 | @weblog.destroy 64 | logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") 65 | end 66 | end 67 | 68 | The result will be a message in your log file along the lines of: 69 | 70 | Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! 71 | 72 | More information on how to use the logger is at http://www.ruby-doc.org/core/ 73 | 74 | Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are 75 | several books available online as well: 76 | 77 | * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) 78 | * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) 79 | 80 | These two books will bring you up to speed on the Ruby language and also on 81 | programming in general. 82 | 83 | 84 | == Debugger 85 | 86 | Debugger support is available through the debugger command when you start your 87 | Mongrel or WEBrick server with --debugger. This means that you can break out of 88 | execution at any point in the code, investigate and change the model, and then, 89 | resume execution! You need to install ruby-debug to run the server in debugging 90 | mode. With gems, use sudo gem install ruby-debug. Example: 91 | 92 | class WeblogController < ActionController::Base 93 | def index 94 | @posts = Post.all 95 | debugger 96 | end 97 | end 98 | 99 | So the controller will accept the action, run the first line, then present you 100 | with a IRB prompt in the server window. Here you can do things like: 101 | 102 | >> @posts.inspect 103 | => "[#You may have mistyped the address or the page may have moved.
24 |Maybe you tried to change something you didn't have access to.
24 |