ifd_tools 0.1.0
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.
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +40 -0
- data/app/admin/emergency_messages.rb +33 -0
- data/app/admin/notifier_updates.rb +42 -0
- data/app/admin/software_updates.rb +42 -0
- data/app/admin/users.rb +48 -0
- data/app/assets/javascripts/ifd_tools/base.js +4 -0
- data/app/assets/javascripts/ifd_tools/fusion_charts.js +361 -0
- data/app/assets/stylesheets/ifd_tools/active_admin/_analytics.scss +32 -0
- data/app/assets/stylesheets/ifd_tools/active_admin/_cleanup.scss +15 -0
- data/app/assets/stylesheets/ifd_tools/active_admin/_footer.scss +87 -0
- data/app/assets/stylesheets/ifd_tools/active_admin/_square_admin_buttons.scss +27 -0
- data/app/assets/stylesheets/ifd_tools/base.scss +4 -0
- data/app/assets/swfs/FCF_Area2D.swf +0 -0
- data/app/assets/swfs/usa_map.swf +0 -0
- data/app/controllers/ifd_tools/application_controller.rb +4 -0
- data/app/helpers/ifd_tools/application_helper.rb +30 -0
- data/app/models/ifd_tools/emergency_message.rb +27 -0
- data/app/models/ifd_tools/notifier_update.rb +28 -0
- data/app/models/ifd_tools/software_update.rb +28 -0
- data/app/models/ifd_tools/tracking/application_event.rb +6 -0
- data/app/models/ifd_tools/tracking/event.rb +51 -0
- data/app/models/ifd_tools/tracking.rb +7 -0
- data/app/uploaders/software_uploader.rb +18 -0
- data/app/views/admin/customers/_trend.html.haml +7 -0
- data/app/views/admin/customers/_trend_info_sidebar.html.haml +11 -0
- data/app/views/admin/customers/demographic_data.builder +11 -0
- data/app/views/admin/customers/events_data.builder +6 -0
- data/app/views/admin/customers/filter_events.js.erb +6 -0
- data/app/views/admin/customers/trends.html.haml +11 -0
- data/app/views/admin/dashboard/_line_graph.html.haml +11 -0
- data/app/views/admin/dashboard/_usa_map.html.haml +2 -0
- data/app/views/admin/emergency_messages/_form.html.haml +6 -0
- data/app/views/admin/notifier_updates/_form.html.haml +9 -0
- data/app/views/admin/shared/_footer.html.haml +6 -0
- data/app/views/admin/software_updates/_form.html.haml +9 -0
- data/app/views/admin/users/_form.html.haml +9 -0
- data/app/views/api/emergency_messages.builder +12 -0
- data/app/views/api/notifier_updates.builder +15 -0
- data/app/views/api/software_updates.builder +15 -0
- data/app/views/api/track.builder +6 -0
- data/app/views/layouts/ifd_tools/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20121010183004_create_ifd_tools_emergency_messages.rb +11 -0
- data/db/migrate/20121011150939_create_ifd_tools_notifier_updates.rb +14 -0
- data/db/migrate/20121011151124_create_ifd_tools_software_updates.rb +14 -0
- data/db/migrate/20121011205911_devise_create_users.rb +57 -0
- data/db/migrate/20121012123505_create_customers.rb +52 -0
- data/db/migrate/20121012133303_create_ifd_tools_tracking_events.rb +14 -0
- data/lib/generators/ifd_tools/install/USAGE +5 -0
- data/lib/generators/ifd_tools/install/install_generator.rb +153 -0
- data/lib/generators/ifd_tools/install/templates/admin/customers.rb +108 -0
- data/lib/generators/ifd_tools/install/templates/admin/dashboard.rb +47 -0
- data/lib/generators/ifd_tools/install/templates/assets/active_admin.css.scss +7 -0
- data/lib/generators/ifd_tools/install/templates/assets/active_admin.js +2 -0
- data/lib/generators/ifd_tools/install/templates/assets/application.css.scss +46 -0
- data/lib/generators/ifd_tools/install/templates/assets/application.js +2 -0
- data/lib/generators/ifd_tools/install/templates/assets/ckeditor.js.coffee +13 -0
- data/lib/generators/ifd_tools/install/templates/capistrano/Capfile +5 -0
- data/lib/generators/ifd_tools/install/templates/capistrano/deploy/production.rb +2 -0
- data/lib/generators/ifd_tools/install/templates/capistrano/deploy/staging.rb +2 -0
- data/lib/generators/ifd_tools/install/templates/capistrano/deploy.rb +50 -0
- data/lib/generators/ifd_tools/install/templates/config/en.yml +17 -0
- data/lib/generators/ifd_tools/install/templates/config/ifd_tools.rb +4 -0
- data/lib/generators/ifd_tools/install/templates/config/schedule.rb.erb +28 -0
- data/lib/generators/ifd_tools/install/templates/controllers/api_controller.rb +8 -0
- data/lib/generators/ifd_tools/install/templates/controllers/application_controller.rb +19 -0
- data/lib/generators/ifd_tools/install/templates/controllers/customer_session_controller.rb +39 -0
- data/lib/generators/ifd_tools/install/templates/foreman/Procfile +2 -0
- data/lib/generators/ifd_tools/install/templates/layouts/application.html.haml +29 -0
- data/lib/generators/ifd_tools/install/templates/layouts/application_logged_out.html.haml +21 -0
- data/lib/generators/ifd_tools/install/templates/models/ability.rb +23 -0
- data/lib/generators/ifd_tools/install/templates/models/customer.rb +60 -0
- data/lib/generators/ifd_tools/install/templates/models/settings.rb +5 -0
- data/lib/generators/ifd_tools/install/templates/models/user.rb +31 -0
- data/lib/generators/ifd_tools/install/templates/settings/application.yml +16 -0
- data/lib/generators/ifd_tools/install/templates/views/customers/_form.html.haml +8 -0
- data/lib/ifd_tools/active_admin/base.rb +18 -0
- data/lib/ifd_tools/api_controller/emergency_messages.rb +9 -0
- data/lib/ifd_tools/api_controller/notifier_updates.rb +9 -0
- data/lib/ifd_tools/api_controller/software_updates.rb +9 -0
- data/lib/ifd_tools/api_controller/tracking.rb +44 -0
- data/lib/ifd_tools/api_controller_extensions.rb +18 -0
- data/lib/ifd_tools/configure.rb +27 -0
- data/lib/ifd_tools/date_time_additions.rb +11 -0
- data/lib/ifd_tools/engine.rb +17 -0
- data/lib/ifd_tools/states.rb +59 -0
- data/lib/ifd_tools/tracking/customer_tracking.rb +143 -0
- data/lib/ifd_tools/tracking/trackable.rb +28 -0
- data/lib/ifd_tools/validations/phone.rb +17 -0
- data/lib/ifd_tools/version.rb +3 -0
- data/lib/ifd_tools.rb +26 -0
- data/lib/tasks/ifd_tools_tasks.rake +2 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +24 -0
- data/test/dummy/log/development.log +15 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/ifd_tools/emergency_messages.yml +11 -0
- data/test/fixtures/ifd_tools/notifier_updates.yml +17 -0
- data/test/fixtures/ifd_tools/software_updates.yml +17 -0
- data/test/fixtures/ifd_tools/tracking/events.yml +17 -0
- data/test/ifd_tools_test.rb +7 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/ifd_tools/emergency_message_test.rb +9 -0
- data/test/unit/ifd_tools/notifier_update_test.rb +9 -0
- data/test/unit/ifd_tools/software_update_test.rb +9 -0
- data/test/unit/ifd_tools/tracking/event_test.rb +9 -0
- metadata +464 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%title= Settings.app_name
|
4
|
+
= stylesheet_link_tag "application", media: "all"
|
5
|
+
= javascript_include_tag "application"
|
6
|
+
= favicon_link_tag
|
7
|
+
= csrf_meta_tags
|
8
|
+
|
9
|
+
%body(class="active_admin logged_in #{params[:controller].gsub('/', '_')} #{params[:action]}")
|
10
|
+
|
11
|
+
#wrapper
|
12
|
+
#header.header
|
13
|
+
|
14
|
+
%h1#site_title.site_title= @page_title || Settings.app_header_name
|
15
|
+
%p#utility_nav.header-item
|
16
|
+
/= link_to "Sign Out", destroy_customer_session_path, method: :delete, title: "Sign Out"
|
17
|
+
|
18
|
+
.flashes
|
19
|
+
- flash.each do |type, message|
|
20
|
+
%div(class="flash flash_#{type}")= message
|
21
|
+
|
22
|
+
#active_admin_content.without_sidebar
|
23
|
+
#main_content_wrapper
|
24
|
+
= yield
|
25
|
+
.clearBoth
|
26
|
+
|
27
|
+
#footer
|
28
|
+
#site_footer
|
29
|
+
= yield :footer
|
@@ -0,0 +1,21 @@
|
|
1
|
+
%html
|
2
|
+
%head
|
3
|
+
%title= Settings.app_name
|
4
|
+
= stylesheet_link_tag "application", media: "all"
|
5
|
+
= javascript_include_tag "application"
|
6
|
+
= csrf_meta_tags
|
7
|
+
|
8
|
+
%body(class="logged_out #{params[:controller].gsub('/', '_')} #{params[:action]}")
|
9
|
+
|
10
|
+
#wrapper
|
11
|
+
#header.header
|
12
|
+
%h1#site_title= @page_title || Settings.app_header_name
|
13
|
+
#content_wrapper
|
14
|
+
- flash.each do |type, message|
|
15
|
+
%div(class="flash flash_#{type}")= message
|
16
|
+
|
17
|
+
#active_admin_content
|
18
|
+
= yield
|
19
|
+
|
20
|
+
#footer
|
21
|
+
= yield :footer
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Ability
|
2
|
+
include CanCan::Ability
|
3
|
+
|
4
|
+
def initialize(user)
|
5
|
+
|
6
|
+
user ||= User.new
|
7
|
+
|
8
|
+
can :manage, :all
|
9
|
+
cannot [:create, :new], Customer
|
10
|
+
|
11
|
+
unless user.super_admin?
|
12
|
+
|
13
|
+
# Only manage regular accounts
|
14
|
+
cannot :manage, User
|
15
|
+
can :manage, User, role: %w(admin)
|
16
|
+
|
17
|
+
# Cannot manage some other sensitive items
|
18
|
+
cannot :manage, [IfdTools::SoftwareUpdate, IfdTools::EmergencyMessage, IfdTools::NotifierUpdate]
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class Customer < ActiveRecord::Base
|
2
|
+
|
3
|
+
Statuses = %w(active banned pending)
|
4
|
+
|
5
|
+
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable, :token_authenticatable, :confirmable
|
6
|
+
|
7
|
+
has_many :tracking_events, :class_name => 'IfdTools::Tracking::Event', dependent: :destroy
|
8
|
+
|
9
|
+
# Setup accessible (or protected) attributes for your model
|
10
|
+
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :phone, :state, :platform
|
11
|
+
|
12
|
+
validates :first_name, :last_name, :email, :state, presence: true
|
13
|
+
validates_phone :phone, presence: true
|
14
|
+
|
15
|
+
default_scope order("lower(first_name) asc, lower(last_name) asc")
|
16
|
+
|
17
|
+
Statuses.each do |s|
|
18
|
+
scope s.to_sym, where(status: s)
|
19
|
+
define_method("#{s}?") { status == s }
|
20
|
+
end
|
21
|
+
|
22
|
+
scope :unconfirmed, where(confirmed_at: nil)
|
23
|
+
scope :top_users, includes(:tracking_events).group("ifd_tools_tracking_events.customer_id").reorder("count(ifd_tools_tracking_events.customer_id) desc, lower(first_name) asc, lower(last_name) asc")
|
24
|
+
|
25
|
+
before_save :ensure_authentication_token
|
26
|
+
before_save :sanitize_phone
|
27
|
+
|
28
|
+
acts_as_url :full_name, limit: 100
|
29
|
+
|
30
|
+
def full_name
|
31
|
+
"#{first_name} #{last_name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def display_name
|
35
|
+
full_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_param
|
39
|
+
url
|
40
|
+
end
|
41
|
+
|
42
|
+
def activate!
|
43
|
+
update_attribute :status, "active"
|
44
|
+
end
|
45
|
+
|
46
|
+
def deactivate!
|
47
|
+
update_attribute :status, "banned"
|
48
|
+
end
|
49
|
+
|
50
|
+
def active?
|
51
|
+
status == "active"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def sanitize_phone
|
57
|
+
self.phone = phone.gsub(/[^0-9]*/, '')
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
|
3
|
+
Roles = %w(admin super_admin)
|
4
|
+
|
5
|
+
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable
|
6
|
+
attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :time_zone, :role
|
7
|
+
|
8
|
+
validates :first_name, :last_name, presence: true
|
9
|
+
|
10
|
+
default_scope order("lower(first_name) asc, lower(last_name) asc")
|
11
|
+
|
12
|
+
after_create { |admin| admin.delay.send_reset_password_instructions }
|
13
|
+
|
14
|
+
def full_name
|
15
|
+
"#{first_name} #{last_name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def display_name
|
19
|
+
full_name
|
20
|
+
end
|
21
|
+
|
22
|
+
Roles.each do |r|
|
23
|
+
define_method("#{r}?") { role == r }
|
24
|
+
scope r.to_sym, where(role: r)
|
25
|
+
end
|
26
|
+
|
27
|
+
def password_required?
|
28
|
+
new_record? ? false : super
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
notifications_email: "notifications@domain.com"
|
3
|
+
app_name: "Name of CMS"
|
4
|
+
app_header_name: "Name of App Header"
|
5
|
+
|
6
|
+
development:
|
7
|
+
<<: *defaults
|
8
|
+
|
9
|
+
test:
|
10
|
+
<<: *defaults
|
11
|
+
|
12
|
+
staging:
|
13
|
+
<<: *defaults
|
14
|
+
|
15
|
+
production:
|
16
|
+
<<: *defaults
|
@@ -0,0 +1,8 @@
|
|
1
|
+
= semantic_form_for [:admin, @customer] do |f|
|
2
|
+
= f.inputs "Customer Information" do
|
3
|
+
= f.input :first_name, label: "First Name"
|
4
|
+
= f.input :last_name, label: "Last Name"
|
5
|
+
= f.input :email
|
6
|
+
= f.input :phone, input_html: { value: phone_number(@customer.phone) }
|
7
|
+
= f.input :state, as: :select, collection: IfdTools::States::all.invert
|
8
|
+
= f.buttons
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ActiveAdmin
|
2
|
+
module Views
|
3
|
+
module Pages
|
4
|
+
class Base# < Arbre::HTML::Document
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
# Renders the content for the footer
|
9
|
+
def build_footer
|
10
|
+
div :id => "footer" do
|
11
|
+
text_node(render 'admin/shared/footer')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module IfdTools
|
2
|
+
module ApiController
|
3
|
+
module Tracking
|
4
|
+
|
5
|
+
# Used to record events from the application
|
6
|
+
#
|
7
|
+
# - trackable_type: ("application_event", "product_event") should be the last part of a model name, ie "IfdTools::Tracking::ProductEvent" => "product_event"
|
8
|
+
# - trackable_id: integer pk (null if trackable_type == "application")
|
9
|
+
# #
|
10
|
+
def track
|
11
|
+
|
12
|
+
begin
|
13
|
+
|
14
|
+
unless params[:type].present? && params[:id].present?
|
15
|
+
@error = "Missing 'type' or 'id' parameter"
|
16
|
+
render status: :unprocessable_entity and return
|
17
|
+
end
|
18
|
+
|
19
|
+
case params[:type]
|
20
|
+
when "application_event"
|
21
|
+
@event = IfdTools::Tracking::ApplicationEvent.new
|
22
|
+
|
23
|
+
else
|
24
|
+
@event = "ifd_tools/tracking/#{params[:type]}".camelize.constantize.new
|
25
|
+
@event.assign_trackable_item_by_id(params[:id])
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
unless @event.nil?
|
30
|
+
@event.ip_address = request.remote_ip
|
31
|
+
@event.customer = current_customer
|
32
|
+
@event.platform = IfdTools::Tracking::Event.platform_for_request(request)
|
33
|
+
@event.save!
|
34
|
+
end
|
35
|
+
|
36
|
+
rescue Exception => e
|
37
|
+
@error = e.message
|
38
|
+
render status: :unprocessable_entity
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'ifd_tools/api_controller/emergency_messages'
|
2
|
+
require 'ifd_tools/api_controller/software_updates'
|
3
|
+
require 'ifd_tools/api_controller/notifier_updates'
|
4
|
+
require 'ifd_tools/api_controller/tracking'
|
5
|
+
|
6
|
+
module IfdTools
|
7
|
+
module ApiControllerExtensions
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
include IfdTools::ApiController::EmergencyMessages
|
12
|
+
include IfdTools::ApiController::SoftwareUpdates
|
13
|
+
include IfdTools::ApiController::NotifierUpdates
|
14
|
+
include IfdTools::ApiController::Tracking
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module IfdTools
|
2
|
+
class Configure
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def dashboard_graph_color=(c)
|
6
|
+
@@dashboard_graph_color = c
|
7
|
+
end
|
8
|
+
|
9
|
+
def dashboard_graph_color
|
10
|
+
@@dashboard_graph_color ||= "AFD8F8"
|
11
|
+
end
|
12
|
+
|
13
|
+
def dashboard_graph_main_color=(c)
|
14
|
+
@@dashboard_graph_main_color = c
|
15
|
+
end
|
16
|
+
|
17
|
+
def dashboard_graph_main_color
|
18
|
+
@@dashboard_graph_main_color ||= "114B78"
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup(&block)
|
22
|
+
block.call(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module IfdTools
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace IfdTools
|
4
|
+
|
5
|
+
initializer "ifd_tools.load_static_assets" do |app|
|
6
|
+
app.middleware.use ::ActionDispatch::Static, "#{root}/public"
|
7
|
+
end
|
8
|
+
|
9
|
+
initializer "ifd_tools.active_admin" do |app|
|
10
|
+
ActiveAdmin::Event.subscribe ActiveAdmin::Application::BeforeLoadEvent do |app|
|
11
|
+
require 'ifd_tools/tracking/customer_tracking'
|
12
|
+
app.load_paths << File.expand_path( File.dirname(__FILE__) + "../../../app/admin" )
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module IfdTools
|
2
|
+
module States
|
3
|
+
def self.all
|
4
|
+
state_abbr = {
|
5
|
+
'AL' => 'Alabama',
|
6
|
+
'AK' => 'Alaska',
|
7
|
+
'AZ' => 'Arizona',
|
8
|
+
'AR' => 'Arkansas',
|
9
|
+
'CA' => 'California',
|
10
|
+
'CO' => 'Colorado',
|
11
|
+
'CT' => 'Connecticut',
|
12
|
+
'DE' => 'Delaware',
|
13
|
+
'DC' => 'District of Columbia',
|
14
|
+
'FL' => 'Florida',
|
15
|
+
'GA' => 'Georgia',
|
16
|
+
'HI' => 'Hawaii',
|
17
|
+
'ID' => 'Idaho',
|
18
|
+
'IL' => 'Illinois',
|
19
|
+
'IN' => 'Indiana',
|
20
|
+
'IA' => 'Iowa',
|
21
|
+
'KS' => 'Kansas',
|
22
|
+
'KY' => 'Kentucky',
|
23
|
+
'LA' => 'Louisiana',
|
24
|
+
'ME' => 'Maine',
|
25
|
+
'MD' => 'Maryland',
|
26
|
+
'MA' => 'Massachusetts',
|
27
|
+
'MI' => 'Michigan',
|
28
|
+
'MN' => 'Minnesota',
|
29
|
+
'MS' => 'Mississippi',
|
30
|
+
'MO' => 'Missouri',
|
31
|
+
'MT' => 'Montana',
|
32
|
+
'NE' => 'Nebraska',
|
33
|
+
'NV' => 'Nevada',
|
34
|
+
'NH' => 'New Hampshire',
|
35
|
+
'NJ' => 'New Jersey',
|
36
|
+
'NM' => 'New Mexico',
|
37
|
+
'NY' => 'New York',
|
38
|
+
'NC' => 'North Carolina',
|
39
|
+
'ND' => 'North Dakota',
|
40
|
+
'OH' => 'Ohio',
|
41
|
+
'OK' => 'Oklahoma',
|
42
|
+
'OR' => 'Oregon',
|
43
|
+
'PA' => 'Pennsylvania',
|
44
|
+
'RI' => 'Rhode Island',
|
45
|
+
'SC' => 'South Carolina',
|
46
|
+
'SD' => 'South Dakota',
|
47
|
+
'TN' => 'Tennessee',
|
48
|
+
'TX' => 'Texas',
|
49
|
+
'UT' => 'Utah',
|
50
|
+
'VT' => 'Vermont',
|
51
|
+
'VA' => 'Virginia',
|
52
|
+
'WA' => 'Washington',
|
53
|
+
'WV' => 'West Virginia',
|
54
|
+
'WI' => 'Wisconsin',
|
55
|
+
'WY' => 'Wyoming'
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module IfdTools
|
2
|
+
module Tracking
|
3
|
+
module CustomerTracking
|
4
|
+
|
5
|
+
def self.included(dsl)
|
6
|
+
|
7
|
+
# Action item to view trends of the resource
|
8
|
+
dsl.action_item only: [:show, :edit] do
|
9
|
+
link_to "Trends", [:trends, :admin, resource]
|
10
|
+
end
|
11
|
+
|
12
|
+
# Actual controller action for viewing the trends
|
13
|
+
dsl.send(:member_action, :trends) do
|
14
|
+
@customer = Customer.find_by_url! params[:id]
|
15
|
+
@trends = IfdTools::Tracking::Event.where(customer_id: @customer.id).limit(75)
|
16
|
+
@registration_date = @customer.created_at
|
17
|
+
@application_launches = IfdTools::Tracking::ApplicationEvent.where(customer_id: @customer.id).count
|
18
|
+
end
|
19
|
+
|
20
|
+
# Sidebar when viewing trends for resource
|
21
|
+
dsl.sidebar :trend_info, only: :trends
|
22
|
+
|
23
|
+
# Provides XML for the USA map
|
24
|
+
dsl.send(:collection_action, :demographic_data) do
|
25
|
+
|
26
|
+
@total_activity = IfdTools::Tracking::Event.count
|
27
|
+
@activity = []
|
28
|
+
|
29
|
+
db_activity_per_state = IfdTools::Tracking::Event.includes(:customer).group("customers.state").count
|
30
|
+
users_per_state = Customer.group(:state).count
|
31
|
+
|
32
|
+
IfdTools::States::all.each do |state, long_name|
|
33
|
+
@activity << OpenStruct.new(name: long_name, activity: db_activity_per_state[state] || 0.00, users: users_per_state[state] || 0)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
dsl.send(:collection_action, :filter_events, method: :post) do
|
39
|
+
|
40
|
+
cookies[:filter_events] = params[:q].to_yaml
|
41
|
+
respond_to do |format|
|
42
|
+
format.js
|
43
|
+
format.html { redirect_to admin_dashboard_url }
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# Provides XML for FusionCharts content graph on dashboard
|
49
|
+
dsl.send(:collection_action, :events_data) do
|
50
|
+
|
51
|
+
filters = YAML.load(cookies[:filter_events]).symbolize_keys rescue {}
|
52
|
+
@color = IfdTools::Configure.dashboard_graph_color
|
53
|
+
@events = IfdTools::Tracking::Event.scoped
|
54
|
+
|
55
|
+
unless filters.empty?
|
56
|
+
|
57
|
+
@events = IfdTools::Tracking::Event.search(filters)
|
58
|
+
if filters[:timestamp_gte].present? and filters[:timestamp_lte].present?
|
59
|
+
@time_range = "Between #{filters[:timestamp_gte]} and #{filters[:timestamp_lte]}"
|
60
|
+
elsif filters[:timestamp_gte].present?
|
61
|
+
@time_range = "Since #{filters[:timestamp_gte]}"
|
62
|
+
elsif filters[:timestamp_lte].present?
|
63
|
+
@time_range = "Before #{filters[:timestamp_lte]}"
|
64
|
+
end
|
65
|
+
|
66
|
+
@filter_type = filters[:type_eq].gsub("IfdTools::Tracking::", "").titleize rescue nil
|
67
|
+
@filter_type = "Everything" if @filter_type.blank?
|
68
|
+
|
69
|
+
@caption = "Activity #{@time_range || 'for All Time'}"
|
70
|
+
@subcaption = "Type: #{@filter_type}"
|
71
|
+
|
72
|
+
@subcaption << " (Mac)" if filters[:platform_eq] == "mac"
|
73
|
+
@subcaption << " (PC)" if filters[:platform_eq] == "pc"
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
# Grab the date/value pairs from the db
|
78
|
+
@events = @events.group("date(timestamp)")
|
79
|
+
|
80
|
+
# Depending on how many records exist, want to narrow that down a good bit
|
81
|
+
distribution = @events.count
|
82
|
+
first_date = distribution.keys.first.to_date
|
83
|
+
last_date = distribution.keys.last.to_date
|
84
|
+
num_days_in_time_span = (first_date..last_date).count rescue 0
|
85
|
+
|
86
|
+
grouping = :days
|
87
|
+
if num_days_in_time_span > 450 # ~ 15 months
|
88
|
+
@events = @events.group_by { |e| e.timestamp.beginning_of_year.to_date }
|
89
|
+
grouping = :years
|
90
|
+
elsif num_days_in_time_span > 175 # 7 weeks
|
91
|
+
@events = @events.group_by { |e| e.timestamp.beginning_of_month.to_date }
|
92
|
+
grouping = :months
|
93
|
+
elsif num_days_in_time_span > 25 # 25 days
|
94
|
+
@events = @events.group_by { |e| e.timestamp.beginning_of_week.to_date }
|
95
|
+
grouping = :weeks
|
96
|
+
else
|
97
|
+
@events = @events.count
|
98
|
+
end
|
99
|
+
|
100
|
+
# End up with Hash of date => count pairs
|
101
|
+
unless grouping == :days
|
102
|
+
@events.delete_if { |k, v| v.nil? }.map { |date, arr| @events[date] = arr.count }
|
103
|
+
end
|
104
|
+
|
105
|
+
# Start/end dates might have changed
|
106
|
+
first_date = @events.keys.first.to_date
|
107
|
+
last_date = @events.keys.last.to_date
|
108
|
+
|
109
|
+
date_step =
|
110
|
+
case grouping
|
111
|
+
when :years
|
112
|
+
1.year
|
113
|
+
when :months
|
114
|
+
1.month
|
115
|
+
when :weeks
|
116
|
+
1.week
|
117
|
+
else
|
118
|
+
1.day
|
119
|
+
end
|
120
|
+
|
121
|
+
# Was using a gorgeous "first_date.step(last_date, 1.month).to_a" syntax, but that didn't work in Ruby 1.9.3 for some reason
|
122
|
+
event_keys = []
|
123
|
+
unless first_date.nil?
|
124
|
+
curr_date = first_date.dup
|
125
|
+
until curr_date > last_date do
|
126
|
+
event_keys << curr_date.to_s
|
127
|
+
curr_date += date_step
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# End up with just { date => FixNum } pairs, with zero values for dates that weren't in the db
|
132
|
+
@events = event_keys.inject({}) { |k, v| k[v] = 0; k }.merge(@events)
|
133
|
+
|
134
|
+
# Only wanted to use this for one request only
|
135
|
+
cookies.delete(:filter_events)
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module IfdTools
|
2
|
+
module Trackable
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
has_many :tracking_events, :class_name => 'IfdTools::Tracking::Event', foreign_key: :trackable_id, dependent: :destroy
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def trackable_title
|
11
|
+
name rescue title
|
12
|
+
end
|
13
|
+
|
14
|
+
def trackable_type
|
15
|
+
self.class.name.titleize
|
16
|
+
end
|
17
|
+
|
18
|
+
# Override if you might want to link to something else
|
19
|
+
def trackable_resource
|
20
|
+
self
|
21
|
+
end
|
22
|
+
|
23
|
+
def trackable_activity
|
24
|
+
tracking_events.count
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module IfdTools
|
2
|
+
module Validations
|
3
|
+
|
4
|
+
module Phone
|
5
|
+
def validates_phone(*args)
|
6
|
+
options = { :format => { :with => /^\(?\d{3}\)?\s*[-|.]?\s*\d{3}\s*[-|.]?\d{4}\s*$/, :message => "'%{value}' is not a valid phone number" } }
|
7
|
+
if !args.empty? and args.last.is_a?(Hash)
|
8
|
+
options.merge! args.pop
|
9
|
+
end
|
10
|
+
args.each { |attribute| validates attribute.to_sym, options }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
ActiveRecord::Base.send(:extend, IfdTools::Validations::Phone)
|
data/lib/ifd_tools.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'carrierwave'
|
2
|
+
require 'cancan'
|
3
|
+
require 'active_admin'
|
4
|
+
require 'delayed_job_active_record'
|
5
|
+
require 'devise-async'
|
6
|
+
require 'cocoon'
|
7
|
+
require 'compass-rails'
|
8
|
+
require 'ckeditor-rails'
|
9
|
+
require 'stringex'
|
10
|
+
require 'daemons'
|
11
|
+
require 'haml'
|
12
|
+
require 'swfobject-rails'
|
13
|
+
|
14
|
+
require "ifd_tools/engine"
|
15
|
+
require 'ifd_tools/date_time_additions'
|
16
|
+
require 'ifd_tools/active_admin/base'
|
17
|
+
require 'ifd_tools/validations/phone'
|
18
|
+
|
19
|
+
module IfdTools
|
20
|
+
|
21
|
+
autoload :ApiControllerExtensions, 'ifd_tools/api_controller_extensions'
|
22
|
+
autoload :Configure, 'ifd_tools/configure'
|
23
|
+
autoload :States, 'ifd_tools/states'
|
24
|
+
autoload :Trackable, 'ifd_tools/tracking/trackable'
|
25
|
+
|
26
|
+
end
|