sir_tracks_alot 0.4.0 → 0.6.2

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.
Files changed (38) hide show
  1. data/Gemfile +2 -1
  2. data/Gemfile.lock +54 -0
  3. data/README.rdoc +29 -1
  4. data/VERSION +1 -1
  5. data/benchmarks/activity_benchmark.rb +22 -23
  6. data/benchmarks/benchmark_helper.rb +30 -0
  7. data/benchmarks/count_benchmark.rb +33 -0
  8. data/lib/sir_tracks_alot.rb +16 -14
  9. data/lib/sir_tracks_alot/activity.rb +7 -6
  10. data/lib/sir_tracks_alot/clock.rb +4 -0
  11. data/lib/sir_tracks_alot/count.rb +87 -39
  12. data/lib/sir_tracks_alot/event_helper.rb +1 -1
  13. data/lib/sir_tracks_alot/filter_helper.rb +28 -18
  14. data/lib/sir_tracks_alot/persistable.rb +4 -0
  15. data/lib/sir_tracks_alot/queue/report_cache.rb +2 -0
  16. data/lib/sir_tracks_alot/queue/report_config.rb +3 -0
  17. data/lib/sir_tracks_alot/queue/report_queue.rb +8 -10
  18. data/lib/sir_tracks_alot/reports/actor_activity_report.rb +3 -3
  19. data/lib/sir_tracks_alot/reports/basic_report.rb +1 -1
  20. data/lib/sir_tracks_alot/reports/filter_report.rb +5 -11
  21. data/lib/sir_tracks_alot/reports/report.rb +16 -2
  22. data/lib/sir_tracks_alot/reports/simple_report.rb +43 -0
  23. data/lib/sir_tracks_alot/reports/target_report.rb +2 -7
  24. data/lib/sir_tracks_alot/summary.rb +9 -0
  25. data/sir_tracks_alot.gemspec +140 -0
  26. data/spec/activity_spec.rb +18 -59
  27. data/spec/count_spec.rb +56 -25
  28. data/spec/queue/report_queue_spec.rb +8 -8
  29. data/spec/redis_spec_helper.rb +8 -0
  30. data/spec/reports/actor_report_spec.rb +16 -16
  31. data/spec/reports/filter_report_spec.rb +1 -1
  32. data/spec/reports/report_spec.rb +15 -0
  33. data/spec/reports/root_stem_report_spec.rb +1 -1
  34. data/spec/reports/simple_report_spec.rb +63 -0
  35. data/spec/reports/target_report_spec.rb +9 -4
  36. data/spec/sir_tracks_alot_spec.rb +4 -0
  37. data/spec/spec_helper.rb +1 -9
  38. metadata +38 -10
@@ -1,6 +1,6 @@
1
1
  module SirTracksAlot
2
2
  module EventHelper
3
- DATE_FORMATS = {:hourly => '%Y/%m/%d %H', :daily => '%Y/%m/%d'}
3
+ DATE_FORMATS = {:hourly => '%Y/%m/%d %H:00', :daily => '%Y/%m/%d'}
4
4
 
5
5
  def views(resolution = nil)
6
6
  return events.size if resolution.nil?
@@ -5,33 +5,43 @@ module SirTracksAlot
5
5
  # Regular Expression filters match against retrieved attribute values
6
6
  #
7
7
  # filter(:actor => 'user1', :target => /\/targets\/\d+/, :action => ['view', 'create'], :category => ['/root', '/other_root'])
8
- def filter(options_for_find, &block)
8
+ def filter(filters, &block)
9
9
  items = []
10
10
  all = []
11
11
 
12
- strings, matchers, arrays = extract_filter_options(options_for_find)
12
+ filters = [filters] unless filters.kind_of?(Array)
13
13
 
14
- unless arrays.empty?
15
- (arrays.values.inject{|a, b| a.product b}).each do |combo|
16
- terms = {}; combo.each{|c| terms[find_key_from_value(arrays, c)] = c}
17
- all += find(terms.merge(strings)).to_a
18
- end
19
- else
20
- all = find(strings)
21
- end
14
+ filters.each do |options_for_find|
15
+ strings, matchers, arrays = extract_filter_options(options_for_find)
22
16
 
23
- all.each do |item|
24
- pass = true
25
-
26
- matchers.each do |key, matcher|
27
- pass = false if !matcher.match(item.send(key))
17
+ unless arrays.empty?
18
+ (arrays.values.inject{|a, b| a.product b}).each do |combo|
19
+ combo = [combo] unless combo.kind_of?(Array)
20
+ terms = {}; combo.each{|c| terms[find_key_from_value(arrays, c)] = c}
21
+ if terms.values.detect{|t| t.kind_of?(Regexp)}
22
+ matchers.merge!(terms)
23
+ next
24
+ end
25
+
26
+ all += find(terms.merge(strings)).to_a
27
+ end
28
+ else
29
+ all += find(strings).to_a
28
30
  end
29
31
 
30
- next unless pass
32
+ all.each do |item|
33
+ pass = true
34
+
35
+ matchers.each do |key, matcher|
36
+ pass = false if !matcher.match(item.send(key))
37
+ end
38
+
39
+ next unless pass
31
40
 
32
- yield item if block_given?
41
+ # yield item if block_given?
33
42
 
34
- items << item
43
+ items << item
44
+ end
35
45
  end
36
46
 
37
47
  items
@@ -24,6 +24,10 @@ module SirTracksAlot
24
24
  self.id == comparee.id
25
25
  end
26
26
 
27
+ def to_hash
28
+ super
29
+ end
30
+
27
31
 
28
32
  protected
29
33
 
@@ -4,8 +4,10 @@ module SirTracksAlot
4
4
  attribute :created_at
5
5
  attribute :report
6
6
  attribute :owner
7
+ attribute :name
7
8
  attribute :html
8
9
 
10
+ index :name
9
11
  index :report
10
12
  index :owner
11
13
  end
@@ -6,9 +6,11 @@ module SirTracksAlot
6
6
 
7
7
  attribute :created_at
8
8
  attribute :report
9
+ attribute :name
9
10
  attribute :owner
10
11
  attribute :options_store
11
12
 
13
+ index :name
12
14
  index :report
13
15
  index :owner
14
16
 
@@ -24,6 +26,7 @@ module SirTracksAlot
24
26
  def validate
25
27
  assert_present :report
26
28
  assert_present :owner
29
+ assert_present :name
27
30
  end
28
31
  end
29
32
  end
@@ -8,9 +8,9 @@ module SirTracksAlot
8
8
  index :name
9
9
  list :queue # of ReportConfigs
10
10
 
11
- def self.push(owner, report, options)
12
- config = ReportConfig.find_or_create(:owner => owner.to_s, :report => report.to_s)
13
- config.options = options.merge(:owner => owner.to_s) # reports require owner, should be sync'd with config owner
11
+ def self.push(owner, report, name, options)
12
+ config = ReportConfig.find_or_create(:owner => owner.to_s, :report => report.to_s, :name => name.to_s)
13
+ config.options = options
14
14
  queue = self.find_or_create(:name => QUEUE_NAME)
15
15
  queue.queue << config.id
16
16
  end
@@ -23,13 +23,12 @@ module SirTracksAlot
23
23
  return false
24
24
  end
25
25
 
26
- queue = queue.first
26
+ queue = queue.first
27
+ config = ReportConfig[queue.queue.pop] # raw gets us just the id's, pop to remove the las one, it's a queue!
27
28
 
28
- config = ReportConfig[queue.queue.pop] # raw gets us just the id's, pop to remove the las one, it's a queue!
29
-
30
29
  process(config)
31
30
  end
32
-
31
+
33
32
  def self.process(config)
34
33
  return false if config.nil?
35
34
 
@@ -37,9 +36,8 @@ module SirTracksAlot
37
36
 
38
37
  begin
39
38
  report = QueueHelper.constantize(QueueHelper.camelize("SirTracksAlot::Reports::#{config.report.capitalize}"))
40
- counts = Count.filter(config.options)
41
- html = report.render_html(:counts => counts)
42
- cache = ReportCache.find_or_create(:owner => config.owner, :report => config.report)
39
+ html = report.render_html(config.options)
40
+ cache = ReportCache.find_or_create(:owner => config.owner, :report => config.report, :name => config.name)
43
41
  cache.update(:html => html)
44
42
  rescue Exception => e
45
43
  SirTracksAlot.log.fatal("Error building report #{config.report} for #{config.owner}: #{e}")
@@ -24,12 +24,12 @@ module SirTracksAlot
24
24
  t << [target, count[0], count[1]]
25
25
  end
26
26
  end
27
-
27
+
28
28
  table.sort_rows_by!('page views', :order => :descending)
29
-
29
+
30
30
  self.data = table
31
31
  end
32
-
32
+
33
33
  module Helpers
34
34
  include Report::Helpers
35
35
  end
@@ -13,7 +13,7 @@ module SirTracksAlot
13
13
 
14
14
  self.data = grouping
15
15
  end
16
-
16
+
17
17
  module Helpers
18
18
  include Report::Helpers
19
19
  end
@@ -8,17 +8,10 @@ module SirTracksAlot
8
8
 
9
9
  # Build up reports by filtering things. Filters are applied and assigned a row title.
10
10
  #
11
- # SirTracksAlot::Reports::FilterReport.render_html(
12
- # :actions => ['view', 'search']
13
- #
14
11
  # :filters = {
15
12
  # 'Title' => {:category => 'category', :target => /\/categories/}
16
13
  # }
17
14
  #
18
- # :filters => {
19
- # :only => {Profile Pages' => {:target => /^\/user_profiles\/.+$/}}
20
- # :except => {Profile Index' => {:target => /^\/user_profiles$/}}
21
- # })
22
15
  def setup
23
16
  super
24
17
 
@@ -26,12 +19,13 @@ module SirTracksAlot
26
19
  options.filters ||= {}
27
20
  options.column_names ||= COLUMN_NAMES
28
21
 
29
-
30
22
  options.filters.each do |title, options_for_find|
31
23
  Count.filter(options_for_find.merge(:owner => options.owner)).each do |count|
32
- counts[title] ||= [0,0]
33
- counts[title][0] += count.visits.to_i
34
- counts[title][1] += count.views.to_i
24
+ count.summaries.each do |summary|
25
+ counts[title] ||= [0,0]
26
+ counts[title][0] += summary.visits.to_i
27
+ counts[title][1] += summary.views.to_i
28
+ end
35
29
  end
36
30
  end
37
31
 
@@ -3,12 +3,26 @@ module SirTracksAlot
3
3
  class Report < Ruport::Controller
4
4
  attr_accessor :all
5
5
 
6
+ # Accepts either:
7
+ # options: {'title' => {:owner => 'xxx'}}
8
+ # options: [{:owner => 'xxx'}]
9
+ def self.build_rows(filters)
10
+ rows = []
11
+ filters = {nil => filters} if filters.kind_of?(Array)
12
+
13
+ filters.each do |title, options_for_find|
14
+ rows += SirTracksAlot::Count.rows(options_for_find, title)
15
+ end
16
+
17
+ rows
18
+ end
19
+
6
20
  def setup
7
21
  self.data = []
8
22
  options.report_class ||= ''
9
23
  options.report_title ||= 'Report'
10
- end
11
-
24
+ end
25
+
12
26
  module Helpers
13
27
  def self.handle(name, &block)
14
28
  @@handlers ||= {}
@@ -0,0 +1,43 @@
1
+ module SirTracksAlot
2
+ module Reports
3
+ class SimpleReport < Report
4
+ COLUMN_NAMES = ['target', 'page views', 'visits']
5
+
6
+ stage :simple
7
+
8
+ def setup
9
+ options.column_names ||= COLUMN_NAMES
10
+
11
+ rows = Report.build_rows(options.filters)
12
+
13
+ table = Table(options.column_names, :data => rows)
14
+
15
+ if options.group
16
+ grouping = Grouping(table, :by => options.group, :order => options.group)
17
+ grouping.each{|n, g| g.sort_rows_by!('count', :order => :descending)}
18
+ self.data = grouping
19
+ else
20
+ table.sort_rows_by!('page views', :order => :descending)
21
+ self.data = table
22
+ end
23
+
24
+ end
25
+
26
+ module Helpers
27
+ include Report::Helpers
28
+ end
29
+
30
+ class HTML < Ruport::Formatter::HTML
31
+ renders :html, :for => SimpleReport
32
+
33
+ build :simple do
34
+ if options.group
35
+ output << erb((options.template || TRACKABLE_ROOT+"/views/reports/group.html.erb"), :binding => binding)
36
+ else
37
+ output << erb((options.template || TRACKABLE_ROOT+"/views/reports/table.html.erb"), :binding => binding)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -8,14 +8,9 @@ module SirTracksAlot
8
8
  def setup
9
9
  super
10
10
  column_names = options.column_names || COLUMN_NAMES
11
- counts = options.counts || {}
12
-
13
- table = Table(column_names) do |t|
14
- counts.each do |count|
15
- t << [count.target, count.visits, count.views]
16
- end
17
- end
11
+ rows = options.rows || []
18
12
 
13
+ table = Table(column_names, :data => rows)
19
14
  table.sort_rows_by!('page views', :order => :descending)
20
15
 
21
16
  self.data = table
@@ -0,0 +1,9 @@
1
+ module SirTracksAlot
2
+ class Summary < Persistable
3
+ attribute :date # 234234234
4
+ attribute :views
5
+ attribute :visits
6
+
7
+ index :date
8
+ end
9
+ end
@@ -0,0 +1,140 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{sir_tracks_alot}
8
+ s.version = "0.6.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Peter T. Brown"]
12
+ s.date = %q{2010-10-18}
13
+ s.description = %q{A high speed general purpose tracking and reporting tool which uses Redis.}
14
+ s.email = %q{peter@flippyhead.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ "Gemfile",
21
+ "Gemfile.lock",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "benchmarks/activity_benchmark.rb",
27
+ "benchmarks/benchmark_helper.rb",
28
+ "benchmarks/count_benchmark.rb",
29
+ "benchmarks/report_benchmark.rb",
30
+ "lib/sir_tracks_alot.rb",
31
+ "lib/sir_tracks_alot/activity.rb",
32
+ "lib/sir_tracks_alot/clock.rb",
33
+ "lib/sir_tracks_alot/count.rb",
34
+ "lib/sir_tracks_alot/event_helper.rb",
35
+ "lib/sir_tracks_alot/filter_helper.rb",
36
+ "lib/sir_tracks_alot/persistable.rb",
37
+ "lib/sir_tracks_alot/queue/queue_helper.rb",
38
+ "lib/sir_tracks_alot/queue/report_cache.rb",
39
+ "lib/sir_tracks_alot/queue/report_config.rb",
40
+ "lib/sir_tracks_alot/queue/report_queue.rb",
41
+ "lib/sir_tracks_alot/reports/activity_report.rb",
42
+ "lib/sir_tracks_alot/reports/actor_activity_report.rb",
43
+ "lib/sir_tracks_alot/reports/actor_report.rb",
44
+ "lib/sir_tracks_alot/reports/basic_report.rb",
45
+ "lib/sir_tracks_alot/reports/filter_report.rb",
46
+ "lib/sir_tracks_alot/reports/report.rb",
47
+ "lib/sir_tracks_alot/reports/root_stem_report.rb",
48
+ "lib/sir_tracks_alot/reports/simple_report.rb",
49
+ "lib/sir_tracks_alot/reports/target_report.rb",
50
+ "lib/sir_tracks_alot/reports/trackable_report.rb",
51
+ "lib/sir_tracks_alot/summary.rb",
52
+ "sir_tracks_alot.gemspec",
53
+ "spec/activity_spec.rb",
54
+ "spec/count_spec.rb",
55
+ "spec/queue/report_config_spec.rb",
56
+ "spec/queue/report_queue_spec.rb",
57
+ "spec/redis_spec_helper.rb",
58
+ "spec/reports/activity_report_spec.rb",
59
+ "spec/reports/actor_activity_report_spec.rb",
60
+ "spec/reports/actor_report_spec.rb",
61
+ "spec/reports/basic_report_spec.rb",
62
+ "spec/reports/filter_report_spec.rb",
63
+ "spec/reports/report_spec.rb",
64
+ "spec/reports/root_stem_report_spec.rb",
65
+ "spec/reports/shared_report_specs.rb",
66
+ "spec/reports/simple_report_spec.rb",
67
+ "spec/reports/target_report_spec.rb",
68
+ "spec/sir_tracks_alot_spec.rb",
69
+ "spec/spec.opts",
70
+ "spec/spec_helper.rb",
71
+ "test/helper.rb",
72
+ "test/test_sir_tracks_alot.rb",
73
+ "views/reports/group.html.erb",
74
+ "views/reports/table.html.erb"
75
+ ]
76
+ s.homepage = %q{http://github.com/flippyhead/sir_tracks_alot}
77
+ s.rdoc_options = ["--charset=UTF-8"]
78
+ s.require_paths = ["lib"]
79
+ s.rubygems_version = %q{1.3.7}
80
+ s.summary = %q{A high speed general purpose tracking and reporting tool which uses Redis.}
81
+ s.test_files = [
82
+ "spec/activity_spec.rb",
83
+ "spec/count_spec.rb",
84
+ "spec/queue/report_config_spec.rb",
85
+ "spec/queue/report_queue_spec.rb",
86
+ "spec/redis_spec_helper.rb",
87
+ "spec/reports/activity_report_spec.rb",
88
+ "spec/reports/actor_activity_report_spec.rb",
89
+ "spec/reports/actor_report_spec.rb",
90
+ "spec/reports/basic_report_spec.rb",
91
+ "spec/reports/filter_report_spec.rb",
92
+ "spec/reports/report_spec.rb",
93
+ "spec/reports/root_stem_report_spec.rb",
94
+ "spec/reports/shared_report_specs.rb",
95
+ "spec/reports/simple_report_spec.rb",
96
+ "spec/reports/target_report_spec.rb",
97
+ "spec/sir_tracks_alot_spec.rb",
98
+ "spec/spec_helper.rb",
99
+ "test/helper.rb",
100
+ "test/test_sir_tracks_alot.rb"
101
+ ]
102
+
103
+ if s.respond_to? :specification_version then
104
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
105
+ s.specification_version = 3
106
+
107
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
108
+ s.add_runtime_dependency(%q<logging>, [">= 0"])
109
+ s.add_runtime_dependency(%q<twitter>, [">= 0"])
110
+ s.add_runtime_dependency(%q<ruport>, [">= 0"])
111
+ s.add_runtime_dependency(%q<ohm>, ["= 0.0.38"])
112
+ s.add_runtime_dependency(%q<redis>, [">= 0"])
113
+ s.add_development_dependency(%q<rspec>, [">= 0"])
114
+ s.add_development_dependency(%q<color>, [">= 0"])
115
+ s.add_development_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
116
+ s.add_development_dependency(%q<hpricot>, [">= 0"])
117
+ else
118
+ s.add_dependency(%q<logging>, [">= 0"])
119
+ s.add_dependency(%q<twitter>, [">= 0"])
120
+ s.add_dependency(%q<ruport>, [">= 0"])
121
+ s.add_dependency(%q<ohm>, ["= 0.0.38"])
122
+ s.add_dependency(%q<redis>, [">= 0"])
123
+ s.add_dependency(%q<rspec>, [">= 0"])
124
+ s.add_dependency(%q<color>, [">= 0"])
125
+ s.add_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
126
+ s.add_dependency(%q<hpricot>, [">= 0"])
127
+ end
128
+ else
129
+ s.add_dependency(%q<logging>, [">= 0"])
130
+ s.add_dependency(%q<twitter>, [">= 0"])
131
+ s.add_dependency(%q<ruport>, [">= 0"])
132
+ s.add_dependency(%q<ohm>, ["= 0.0.38"])
133
+ s.add_dependency(%q<redis>, [">= 0"])
134
+ s.add_dependency(%q<rspec>, [">= 0"])
135
+ s.add_dependency(%q<color>, [">= 0"])
136
+ s.add_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
137
+ s.add_dependency(%q<hpricot>, [">= 0"])
138
+ end
139
+ end
140
+