ifd_tools 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|