gcstats 1.0.1 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,7 +12,7 @@ Also available online as a web app: <http://gcstats.heroku.com/>
12
12
  To install, change directory to where you have extracted the gcstats source files and issue:
13
13
 
14
14
  gem build gcstats.gemspec
15
- gem install gcstats-*.gem
15
+ gem install gcstats
16
16
 
17
17
  ## Use ##
18
18
 
data/bin/gcstats CHANGED
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'rubygems'
4
3
  require 'zip/zip'
5
- require 'gcstats/mapping'
4
+ require 'gcstats/caches'
6
5
  require 'gcstats/template'
7
6
 
8
7
  in_fn, out_fn = ARGV[0..1]
@@ -25,18 +24,18 @@ if File.extname(in_fn) == '.zip'
25
24
  end
26
25
  }
27
26
  else
28
- data = File.read(in_fn)
27
+ data = (in_fn == '-') ? $stdin.read : File.read(in_fn)
29
28
  out_fn ||= File.basename(in_fn, File.extname(in_fn)) + '.html'
30
29
  end
31
30
 
32
- libdir = File.join(File.dirname(__FILE__), '..', 'lib', 'gcstats')
31
+ datadir = File.join(File.dirname(__FILE__), '..', 'data', 'gcstats')
33
32
 
34
- rhtml = File.read(File.join(libdir, 'gcstats.rhtml'))
33
+ rhtml = File.read(File.join(datadir, 'gcstats.rhtml'))
35
34
  caches = GCStats::Caches.from_xml(data)
36
35
  data = {:caches => caches, :start_ts => start_ts}
37
36
  html = GCStats::Template.new(rhtml, data).result
38
- html.sub!('/* %css% */', "\n" + File.read(File.join(libdir, 'gcstats.css')))
39
- html.sub!('/* %js% */', "\n" + File.read(File.join(libdir, 'gcstats.js')))
37
+ html.sub!('/* %css% */', "\n" + File.read(File.join(datadir, 'gcstats.css')))
38
+ html.sub!('/* %js% */', "\n" + File.read(File.join(datadir, 'gcstats.js')))
40
39
 
41
40
  if ARGV[1].nil? && caches[0] && caches[0].logs[0]
42
41
  out_fn = caches[0].logs[0].finder
File without changes
@@ -27,7 +27,7 @@ if (!GCStats) {
27
27
  var total_row, row_max, total_col, col_max, inner_cells, table_max;
28
28
 
29
29
  // total row
30
-
30
+
31
31
  total_row = $(table).find('tr.total td');
32
32
 
33
33
  row_max = total_row.slice(0, -1).map(function () {
@@ -69,10 +69,12 @@ if (!GCStats) {
69
69
  };
70
70
 
71
71
  $(document).ready(function () {
72
- GCStats.highlight_table($('#finds_by_day_of_week'));
73
- GCStats.highlight_table($('#finds_by_year'));
74
- GCStats.highlight_table($('#finds_by_date'));
75
- GCStats.highlight_square_table($('#difficulty_terrain_combinations'));
76
- GCStats.highlight_square_table($('#month_day_combinations'));
72
+ $('table.highlight:not(.square)').each(function () {
73
+ GCStats.highlight_table(this);
74
+ });
75
+
76
+ $('table.highlight.square').each(function () {
77
+ GCStats.highlight_square_table(this);
78
+ });
77
79
  });
78
80
  }
@@ -25,7 +25,7 @@
25
25
  </tr>
26
26
  <tr>
27
27
  <th class="l">Archived</th>
28
- <td><%= total_archived %></td>
28
+ <td><%= '%d (%s)' % [total_archived, format_percent(total_archived, total_finds)] %></td>
29
29
  </tr>
30
30
  <tr>
31
31
  <th class="l">Caches/Day</th>
@@ -39,11 +39,25 @@
39
39
  <th class="l">Most in one day</th>
40
40
  <td><%= '%d (%s)' % [most_finds_in_a_day, most_finds_in_a_day_dates.join(', ')] %></td>
41
41
  </tr>
42
+ <tr>
43
+ <th class="l">Oldest cache</th>
44
+ <td>
45
+ <a href="<%=h oldest_cache_found.url %>"><%=h oldest_cache_found.name %></a>
46
+ (<%=h oldest_cache_found.published.strftime('%Y-%m-%d') %>)
47
+ </td>
48
+ </tr>
49
+ <tr>
50
+ <th class="l">Newest cache</th>
51
+ <td>
52
+ <a href="<%=h newest_cache_found.url %>"><%=h newest_cache_found.name %></a>
53
+ (<%=h newest_cache_found.published.strftime('%Y-%m-%d') %>)
54
+ </td>
55
+ </tr>
42
56
  </table>
43
57
  <%# }}} %>
44
58
 
45
59
  <%# {{{ finds by day of week %>
46
- <table id="finds_by_day_of_week">
60
+ <table class="highlight">
47
61
  <caption>Finds by Day of Week</caption>
48
62
  <tr>
49
63
  <th>Day</th>
@@ -54,14 +68,14 @@
54
68
  <tr>
55
69
  <td><%= DAY_NAME[i] %></td>
56
70
  <td class="finds r"><%= finds %></td>
57
- <td class="r"><%= '%.1f' % (finds / total_finds.to_f * 100) %>%</td>
71
+ <td class="r"><%= format_percent(finds, total_finds) %></td>
58
72
  </tr>
59
73
  <% } %>
60
74
  </table>
61
75
  <%# }}} %>
62
76
 
63
77
  <%# {{{ finds by year %>
64
- <table id="finds_by_year">
78
+ <table class="highlight">
65
79
  <caption>Finds by Year</caption>
66
80
  <tr>
67
81
  <th>Year</th>
@@ -72,7 +86,7 @@
72
86
  <tr>
73
87
  <td><%= year %></td>
74
88
  <td class="finds r"><%= finds = finds_by_year[year] %></td>
75
- <td class="r"><%= '%.1f' % (finds / total_finds.to_f * 100) %>%</td>
89
+ <td class="r"><%= format_percent(finds, total_finds) %></td>
76
90
  </tr>
77
91
  <% } %>
78
92
  </table>
@@ -90,7 +104,7 @@
90
104
  <tr>
91
105
  <td><%=h size %></td>
92
106
  <td class="r"><%= finds %></td>
93
- <td class="r"><%= '%.1f' % (finds / total_finds.to_f * 100) %>%</td>
107
+ <td class="r"><%= format_percent(finds, total_finds) %></td>
94
108
  </tr>
95
109
  <% } %>
96
110
  </table>
@@ -108,7 +122,7 @@
108
122
  <tr>
109
123
  <td><%=h type %></td>
110
124
  <td class="r"><%= finds %></td>
111
- <td class="r"><%= '%.1f' % (finds / total_finds.to_f * 100) %>%</td>
125
+ <td class="r"><%= format_percent(finds, total_finds) %></td>
112
126
  </tr>
113
127
  <% } %>
114
128
  </table>
@@ -126,14 +140,14 @@
126
140
  <tr>
127
141
  <td><%=h owner %></td>
128
142
  <td class="r"><%= finds %></td>
129
- <td class="r"><%= '%.1f' % (finds / total_finds.to_f * 100) %>%</td>
143
+ <td class="r"><%= format_percent(finds, total_finds) %></td>
130
144
  </tr>
131
145
  <% } %>
132
146
  </table>
133
147
  <%# }}} %>
134
148
 
135
149
  <%# {{{ difficulty/terrain combinations %>
136
- <table id="difficulty_terrain_combinations" class="c">
150
+ <table class="c highlight square">
137
151
  <caption>Difficulty/Terrain Combinations</caption>
138
152
  <tr>
139
153
  <th>D/T</th>
@@ -162,7 +176,7 @@
162
176
  <%# }}} %>
163
177
 
164
178
  <%# {{{ month/day combinations %>
165
- <table id="month_day_combinations" class="c">
179
+ <table class="c highlight square">
166
180
  <caption>Month/Day Combinations</caption>
167
181
  <tr>
168
182
  <th>M/D</th>
@@ -198,11 +212,11 @@
198
212
  <th>Finds</th>
199
213
  <th>Percentage</th>
200
214
  </tr>
201
- <% finds_by_country.sort {|x, y| y[1] <=> x[1] }.each {|country, finds| %>
215
+ <% finds_by_country.sort {|a, b| b[1] <=> a[1] }.each {|country, finds| %>
202
216
  <tr>
203
217
  <td><%=h country %></td>
204
218
  <td class="r"><%= finds %></td>
205
- <td class="r"><%= '%.1f' % (finds / total_finds.to_f * 100) %>%</td>
219
+ <td class="r"><%= format_percent(finds, total_finds) %></td>
206
220
  </tr>
207
221
  <% } %>
208
222
  </table>
@@ -222,12 +236,12 @@
222
236
  <th>Total</th>
223
237
  </tr>
224
238
  <% country_finds = states.map {|s| s[1] }.sum %>
225
- <% states.sort {|x, y| y[1] <=> x[1] }.each {|state, finds| %>
239
+ <% states.sort {|a, b| b[1] <=> a[1] }.each {|state, finds| %>
226
240
  <tr>
227
241
  <td><%=h state %></td>
228
242
  <td class="r"><%= finds %></td>
229
- <td class="r"><%= '%.1f' % (finds / country_finds.to_f * 100) %>%</td>
230
- <td class="r"><%= '%.1f' % (finds / total_finds.to_f * 100) %>%</td>
243
+ <td class="r"><%= format_percent(finds, country_finds) %></td>
244
+ <td class="r"><%= format_percent(finds, total_finds) %></td>
231
245
  </tr>
232
246
  <% } %>
233
247
  </table>
@@ -235,7 +249,7 @@
235
249
  <%# }}} %>
236
250
 
237
251
  <%# {{{ finds by date %>
238
- <table id="finds_by_date">
252
+ <table class="highlight">
239
253
  <caption>Finds by Date</caption>
240
254
  <tr>
241
255
  <th>Date</th>
File without changes
@@ -22,7 +22,7 @@ module GCStats
22
22
  def days_cached
23
23
  @days_cached ||= begin
24
24
  dates = finds_by_date.keys.sort
25
- (dates[-1] - dates[0]).to_i
25
+ (dates.last - dates.first).to_i
26
26
  end
27
27
  end
28
28
 
@@ -40,15 +40,11 @@ module GCStats
40
40
 
41
41
  def finds_by_date
42
42
  @finds_by_date ||= begin
43
- finds = {}
43
+ finds = Hash.new(0)
44
44
 
45
45
  @caches.each {|cache|
46
46
  cache.find_dates.each {|find_date|
47
- begin
48
- finds[find_date] += 1
49
- rescue
50
- finds[find_date] = 1
51
- end
47
+ finds[find_date] += 1
52
48
  }
53
49
  }
54
50
 
@@ -66,11 +62,7 @@ module GCStats
66
62
  wday = date.wday
67
63
  end
68
64
 
69
- begin
70
- finds[wday] += finds_on_date
71
- rescue
72
- finds[wday] = finds_on_date
73
- end
65
+ finds[wday] += finds_on_date
74
66
  }
75
67
 
76
68
  finds
@@ -78,19 +70,15 @@ module GCStats
78
70
 
79
71
  def finds_by_year
80
72
  @finds_by_year ||= begin
81
- finds = {}
73
+ finds = Hash.new(0)
82
74
 
83
75
  finds_by_date.each {|date, finds_on_date|
84
- begin
85
- finds[date.year] += finds_on_date
86
- rescue
87
- finds[date.year] = finds_on_date
88
- end
76
+ finds[date.year] += finds_on_date
89
77
  }
90
78
 
91
- # fill empty years with 0
79
+ # fill empty inner years with 0
92
80
  (finds.keys.min + 1...finds.keys.max).each {|year|
93
- finds[year] ||= 0
81
+ finds[year] = [0, finds[year]].max
94
82
  }
95
83
 
96
84
  finds
@@ -98,31 +86,23 @@ module GCStats
98
86
  end
99
87
 
100
88
  def finds_by_size
101
- finds = {}
89
+ finds = Hash.new(0)
102
90
 
103
91
  @caches.each {|cache|
104
- begin
105
- finds[cache.container] += cache.find_dates.size
106
- rescue
107
- finds[cache.container] = cache.find_dates.size
108
- end
92
+ finds[cache.container] += cache.find_dates.size
109
93
  }
110
94
 
111
- finds.to_a.sort {|x, y| y[1] <=> x[1] }
95
+ finds.sort {|a, b| b[1] <=> a[1] }
112
96
  end
113
97
 
114
98
  def finds_by_type
115
- finds = {}
99
+ finds = Hash.new(0)
116
100
 
117
101
  @caches.each {|cache|
118
- begin
119
- finds[cache.type] += cache.find_dates.size
120
- rescue
121
- finds[cache.type] = cache.find_dates.size
122
- end
102
+ finds[cache.type] += cache.find_dates.size
123
103
  }
124
104
 
125
- finds.to_a.sort {|x, y| y[1] <=> x[1] }
105
+ finds.sort {|a, b| b[1] <=> a[1] }
126
106
  end
127
107
 
128
108
  def difficulty_terrain_combinations
@@ -162,14 +142,10 @@ module GCStats
162
142
 
163
143
  def finds_by_country
164
144
  @finds_by_country ||= begin
165
- finds = {}
145
+ finds = Hash.new(0)
166
146
 
167
147
  @caches.each {|cache|
168
- begin
169
- finds[cache.country] += cache.find_dates.size
170
- rescue
171
- finds[cache.country] = cache.find_dates.size
172
- end
148
+ finds[cache.country] += cache.find_dates.size
173
149
  }
174
150
 
175
151
  finds
@@ -194,22 +170,26 @@ module GCStats
194
170
 
195
171
  def finds_by_owner
196
172
  @finds_by_owner ||= begin
197
- finds = {}
173
+ finds = Hash.new(0)
198
174
 
199
175
  @caches.each {|cache|
200
- begin
201
- finds[cache.owner] += cache.find_dates.size
202
- rescue
203
- finds[cache.owner] = cache.find_dates.size
204
- end
176
+ finds[cache.owner] += cache.find_dates.size
205
177
  }
206
178
 
207
- finds.sort {|x, y| y[1] <=> x[1] }[0..9]
179
+ finds.sort {|a, b| b[1] <=> a[1] }[0..9]
208
180
  end
209
181
  end
210
182
 
183
+ def oldest_cache_found
184
+ @oldest_cache_found ||= @caches.sort {|a, b| a.published <=> b.published }.first
185
+ end
186
+
187
+ def newest_cache_found
188
+ @newest_cache_found ||= @caches.sort {|a, b| a.published <=> b.published }.last
189
+ end
190
+
211
191
  def geocacher_name
212
- @caches[0].logs[0].finder
192
+ @caches.first.logs.first.finder
213
193
  end
214
194
 
215
195
  def finds_dates
@@ -217,7 +197,11 @@ module GCStats
217
197
  end
218
198
 
219
199
  def render_time
220
- Time.new - @start_ts
200
+ Time.now - @start_ts
201
+ end
202
+
203
+ def format_percent(value, total, precision = 1)
204
+ '%.*f%%' % [precision, value / total.to_f * 100]
221
205
  end
222
206
  end
223
207
  end
@@ -1,11 +1,12 @@
1
- require 'gcstats/mapping'
1
+ require 'gcstats/caches'
2
2
  require 'gcstats/template'
3
- require 'rubygems'
4
3
  require 'zip/zip'
5
4
  require 'sinatra'
6
5
 
7
- get '/' do
8
- %{\
6
+ module GCStats
7
+ module Server
8
+ get '/' do
9
+ %{\
9
10
  <html>
10
11
  <head>
11
12
  <title>gcstats</title>
@@ -23,43 +24,45 @@ get '/' do
23
24
  alt="Fork me on GitHub" /></a>
24
25
  </body>
25
26
  </html>
26
- }
27
- end
27
+ }
28
+ end
28
29
 
29
- post '/generate_stats' do
30
- begin
31
- start_ts = Time.new # for render_time helper
30
+ post '/generate_stats' do
31
+ begin
32
+ start_ts = Time.new # for render_time helper
32
33
 
33
- pq = params['pq']
34
+ pq = params['pq']
34
35
 
35
- if pq[:type] == 'application/zip'
36
- data = nil
36
+ if pq[:type] == 'application/zip'
37
+ data = nil
37
38
 
38
- Zip::ZipFile.foreach(pq[:tempfile].path) {|entry|
39
- if File.extname(entry.name) == '.gpx'
40
- data = entry.get_input_stream.read
41
- break
39
+ Zip::ZipFile.foreach(pq[:tempfile].path) {|entry|
40
+ if File.extname(entry.name) == '.gpx'
41
+ data = entry.get_input_stream.read
42
+ break
43
+ end
44
+ }
45
+ else
46
+ data = pq[:tempfile].read
42
47
  end
43
- }
44
- else
45
- data = pq[:tempfile].read
46
- end
47
48
 
48
- libdir = File.dirname(__FILE__)
49
+ datadir = File.join(File.dirname(__FILE__), '..', '..', 'data', 'gcstats')
49
50
 
50
- rhtml = open(File.join(libdir, 'gcstats.rhtml')).read
51
- caches = GCStats::Caches.from_xml(data)
52
- data = {:caches => caches, :start_ts => start_ts}
53
- html = GCStats::Template.new(rhtml, data).result
54
- html.sub!('/* %css% */', "\n" + File.read(File.join(libdir, 'gcstats.css')))
55
- html.sub!('/* %js% */', "\n" + File.read(File.join(libdir, 'gcstats.js')))
51
+ rhtml = open(File.join(datadir, 'gcstats.rhtml')).read
52
+ caches = GCStats::Caches.from_xml(data)
53
+ data = {:caches => caches, :start_ts => start_ts}
54
+ html = GCStats::Template.new(rhtml, data).result
55
+ html.sub!('/* %css% */', "\n" + File.read(File.join(datadir, 'gcstats.css')))
56
+ html.sub!('/* %js% */', "\n" + File.read(File.join(datadir, 'gcstats.js')))
56
57
 
57
- return html
58
- rescue
59
- halt 500, '<h1>Internal Server Error</h1>'
60
- end
61
- end
58
+ return html
59
+ rescue
60
+ halt 500, '<h1>Internal Server Error</h1>'
61
+ end
62
+ end
62
63
 
63
- not_found do
64
- '<h1>Not Found</h1>'
64
+ not_found do
65
+ '<h1>Not Found</h1>'
66
+ end
67
+ end
65
68
  end
@@ -1,3 +1,3 @@
1
1
  module GCStats
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.3'
3
3
  end