copilot 0.0.7 → 0.0.8

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.
@@ -1,4 +1,5 @@
1
1
  require 'csv'
2
+ require 'hash_flattener'
2
3
 
3
4
  module CoPilot
4
5
  class ArrayToCsvConverter
@@ -19,7 +20,7 @@ module CoPilot
19
20
  private
20
21
 
21
22
  def rows
22
- @rows ||= @array.map { |r| flatten r }
23
+ @rows ||= @array.map { |r| HashFlattener.flatten r }
23
24
  end
24
25
 
25
26
  def columns
@@ -47,25 +48,5 @@ module CoPilot
47
48
  keys.sort
48
49
  end
49
50
 
50
- def flatten(enumerable)
51
- res = {}
52
-
53
- enumerable.each_with_index do |elem, i|
54
- if elem.is_a?(Array)
55
- k, v = elem
56
- else
57
- k, v = i, elem
58
- end
59
-
60
- if v.is_a? Enumerable
61
- res.merge!(flatten k)
62
- else
63
- res[k] = v
64
- end
65
- end
66
-
67
- res
68
- end
69
-
70
51
  end
71
52
  end
@@ -1,5 +1,6 @@
1
- require_relative 'internal/build_table_row'
2
- require_relative 'internal/builds_page'
1
+ require 'time'
2
+ require_relative 'internal/array_limiter'
3
+ require_relative 'internal/pager'
3
4
 
4
5
  module CoPilot
5
6
  class BuildsForBundleIdRequest
@@ -9,45 +10,59 @@ module CoPilot
9
10
  end
10
11
 
11
12
  def send(bundle_id, options={})
12
- @limit = options[:limit]
13
- @since = options[:since]
14
- @builds_page = BuildsPage.new @browser, bundle_id
15
- @builds_page.goto
16
- @builds_page.more_builds
13
+ @bundle_id = bundle_id
17
14
  @builds = []
15
+ @builds_limiter = create_builds_limiter options
16
+ @pager = Pager.new @browser
17
+ go_to_builds_page
18
18
  add_builds_for_each_page
19
- remove_duplicate_builds
20
- strip_excess_builds
21
19
  @builds
22
20
  end
23
21
 
24
22
  private
25
23
 
26
- def add_builds_for_each_page
27
- add_builds
28
- add_builds while @builds_page.next_page && !limit_reached && !age_reached
24
+ def create_builds_limiter(options={})
25
+ l = ArrayLimiter.new @builds, max_number: options[:limit], max_time: options[:since]
26
+ l.time_lambda = lambda { |b| b[:added_date] }
27
+ l.limit_reached_lambda = lambda { @limit_reached = true }
28
+ l
29
29
  end
30
30
 
31
- def add_builds
32
- rows = @builds_page.builds_table_rows
33
- @builds += rows.map { |row| BuildTableRow.new(row).to_hash }
31
+ def go_to_builds_page
32
+ @browser.goto 'https://www.testflightapp.com/dashboard/applications'
33
+ @browser.small(text: @bundle_id).click
34
+ end
35
+
36
+ def add_builds_for_each_page
37
+ until limit_reached? || no_more_builds? do
38
+ add_builds
39
+ end
34
40
  end
35
41
 
36
- def remove_duplicate_builds
37
- @builds.uniq! { |b| b[:id] }
42
+ def limit_reached?
43
+ @limit_reached ||= false
38
44
  end
39
45
 
40
- def strip_excess_builds
41
- @builds = @builds.first @limit if @limit
42
- @builds.select! { |b| b[:added_date] > @since } if @since
46
+ def no_more_builds?
47
+ !@pager.next_page
43
48
  end
44
49
 
45
- def limit_reached
46
- @limit && @builds.length >= @limit
50
+ def add_builds
51
+ rows = @browser.trs(class: 'goversion pointer')
52
+ rows.each { |row| @builds_limiter.add create_build(row) }
47
53
  end
48
54
 
49
- def age_reached
50
- @since && @builds.last[:added_date] > @since
55
+ def create_build(row)
56
+ {
57
+ id: row.id.split('/').last,
58
+ version: row[0].text,
59
+ added_date: Time.parse(row[1].text),
60
+ built_for: row[2].text,
61
+ sdk: row[3].text,
62
+ crashes: row[4].text.to_i,
63
+ feedback: row[5].text.to_i,
64
+ installs: row[6].text.to_i
65
+ }
51
66
  end
52
67
 
53
68
  end
@@ -1,4 +1,5 @@
1
1
  require_relative 'internal/feedback_page'
2
+ require_relative 'internal/array_limiter'
2
3
 
3
4
  module CoPilot
4
5
  class FeedbackForBuildIdRequest
@@ -8,49 +9,56 @@ module CoPilot
8
9
  end
9
10
 
10
11
  def send(build_id, options={})
11
- @limit = options[:limit]
12
- @since = options[:since]
13
12
  @feedback = []
13
+ @feedback_limiter = create_feedback_limiter options
14
14
  @feedback_page = FeedbackPage.new @browser, build_id
15
+ @pager = Pager.new @browser
15
16
  @feedback_page.goto
16
17
  add_feedback_for_each_page
17
- strip_excess_feedback
18
18
  @feedback
19
19
  end
20
20
 
21
21
  private
22
22
 
23
+ def create_feedback_limiter(options={})
24
+ l = ArrayLimiter.new @feedback, max_number: options[:limit], max_time: options[:since]
25
+ l.time_lambda = lambda { |f| f[:date] }
26
+ l.limit_reached_lambda = lambda { @limit_reached = true }
27
+ l
28
+ end
29
+
23
30
  def add_feedback_for_each_page
24
31
  add_feedback
25
- add_feedback while @feedback_page.next_page && !limit_reached && !age_reached
32
+ until limit_reached? || no_more_feedback? do
33
+ add_feedback
34
+ end
35
+ end
36
+
37
+ def limit_reached?
38
+ @limit_reached ||= false
39
+ end
40
+
41
+ def no_more_feedback?
42
+ !@pager.next_page
26
43
  end
27
44
 
28
45
  def add_feedback
29
46
  @feedback_page.expand_details
30
47
  @feedback_page.each_summary_detail_pair do |summary, detail|
31
48
  main_feedback_table = detail.table(class: 'mainfeedback')
32
- @feedback << {
33
- user: summary.tds[0].text,
34
- date: Time.parse(summary.tds[1].text),
35
- subject: summary.tds[2].text,
36
- replies: summary.tds[3].text.to_i,
37
- via: main_feedback_table.ps[0].text,
38
- message: main_feedback_table.ps[1].text
39
- }
49
+ @feedback_limiter.add create_feedback(summary, main_feedback_table)
40
50
  end
41
51
  end
42
52
 
43
- def strip_excess_feedback
44
- @feedback = @feedback.first @limit if @limit
45
- @feedback.select! { |f| f[:date] > @since } if @since
46
- end
47
-
48
- def limit_reached
49
- @limit && @feedback.length >= @limit
50
- end
51
-
52
- def age_reached
53
- @since && @feedback.last[:date] > @since
53
+ def create_feedback(summary, main_feedback_table)
54
+ {
55
+ user: summary.tds[0].text,
56
+ date: Time.parse(summary.tds[1].text),
57
+ subject: summary.tds[2].text,
58
+ replies: summary.tds[3].text.to_i,
59
+ via: main_feedback_table.ps[0].text,
60
+ message: main_feedback_table.ps[1].text
61
+ }
54
62
  end
55
63
 
56
64
  def b
@@ -0,0 +1,29 @@
1
+ module CoPilot
2
+ class ArrayLimiter
3
+
4
+ attr_accessor :time_lambda, :limit_reached_lambda
5
+
6
+ def initialize(array, options={})
7
+ @array = array
8
+ @max_number = options[:max_number]
9
+ @max_time = options[:max_time]
10
+ @time_lambda = lambda { |v| v[:time] }
11
+ @limit_reached_lambda = {}
12
+ end
13
+
14
+ def add(value)
15
+ time = @time_lambda.call value
16
+ limit_reached = max_number_reached?(@array.length) || max_time_reached?(time)
17
+ limit_reached ? @limit_reached_lambda.call : @array << value
18
+ end
19
+
20
+ def max_number_reached?(number)
21
+ @max_number && number >= @max_number
22
+ end
23
+
24
+ def max_time_reached?(time)
25
+ @max_time && time > @max_time
26
+ end
27
+
28
+ end
29
+ end
@@ -19,20 +19,8 @@ module CoPilot
19
19
  summary_rows.to_a.each_index { |i| yield [summary_rows[i], detail_rows[i]] }
20
20
  end
21
21
 
22
- def next_page
23
- link = next_page_link
24
- return false unless link
25
- link.click
26
- true
27
- end
28
-
29
22
  private
30
23
 
31
- def next_page_link
32
- links = b.as(title: 'Next Page')
33
- links.length == 1 ? links[0] : nil
34
- end
35
-
36
24
  def summary_detail_row_pairs
37
25
  pairs = []
38
26
  summary_rows.to_a.each_index { |i| pairs << [summary_rows[i], detail_rows[i]] }
@@ -0,0 +1,24 @@
1
+ module CoPilot
2
+ class Pager
3
+
4
+ def initialize(browser)
5
+ @browser = browser
6
+ end
7
+
8
+ def next_page
9
+ link = next_page_link
10
+ return false unless link
11
+ link.click
12
+ sleep 1
13
+ true
14
+ end
15
+
16
+ private
17
+
18
+ def next_page_link
19
+ links = @browser.as(title: 'Next Page')
20
+ links.length == 1 ? links[0] : nil
21
+ end
22
+
23
+ end
24
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: copilot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-03-08 00:00:00.000000000 Z
12
+ date: 2013-03-14 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: hash_flattener
16
+ requirement: &70291170643440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70291170643440
14
25
  - !ruby/object:Gem::Dependency
15
26
  name: watir-webdriver
16
- requirement: &70328055296520 !ruby/object:Gem::Requirement
27
+ requirement: &70291170638840 !ruby/object:Gem::Requirement
17
28
  none: false
18
29
  requirements:
19
30
  - - ! '>='
@@ -21,7 +32,7 @@ dependencies:
21
32
  version: '0'
22
33
  type: :runtime
23
34
  prerelease: false
24
- version_requirements: *70328055296520
35
+ version_requirements: *70291170638840
25
36
  description:
26
37
  email: matthew-github@matthewriley.name
27
38
  executables: []
@@ -33,9 +44,9 @@ files:
33
44
  - lib/copilot/facade.rb
34
45
  - lib/copilot/requests/builds_for_bundle_id_request.rb
35
46
  - lib/copilot/requests/feedback_for_build_id_request.rb
36
- - lib/copilot/requests/internal/build_table_row.rb
37
- - lib/copilot/requests/internal/builds_page.rb
47
+ - lib/copilot/requests/internal/array_limiter.rb
38
48
  - lib/copilot/requests/internal/feedback_page.rb
49
+ - lib/copilot/requests/internal/pager.rb
39
50
  - lib/copilot/requests.rb
40
51
  - lib/copilot.rb
41
52
  homepage: http://rubygems.org/gems/copilot
@@ -1,61 +0,0 @@
1
- require 'time'
2
-
3
- module CoPilot
4
- class BuildTableRow
5
-
6
- def initialize(tr)
7
- @tr = tr
8
- end
9
-
10
- def build_id
11
- @tr.id.split('/').last
12
- end
13
-
14
- def version
15
- @tr[1].text
16
- end
17
-
18
- def added_date
19
- Time.parse @tr[2].text
20
- end
21
-
22
- def built_for
23
- @tr[3].text
24
- end
25
-
26
- def size
27
- @tr[4].text
28
- end
29
-
30
- def sdk
31
- @tr[5].text
32
- end
33
-
34
- def crashes
35
- @tr[6].text.to_i
36
- end
37
-
38
- def feedback
39
- @tr[7].text.to_i
40
- end
41
-
42
- def installs
43
- @tr[8].text.to_i
44
- end
45
-
46
- def to_hash
47
- {
48
- id: build_id,
49
- version: version,
50
- added_date: added_date,
51
- built_for: built_for,
52
- size: size,
53
- sdk: sdk,
54
- crashes: crashes,
55
- feedback: feedback,
56
- installs: installs
57
- }
58
- end
59
-
60
- end
61
- end
@@ -1,63 +0,0 @@
1
- module CoPilot
2
- class BuildsPage
3
-
4
- def initialize(browser, bundle_id)
5
- @browser = browser
6
- @bundle_id = bundle_id
7
- end
8
-
9
- def goto
10
- b.goto 'https://www.testflightapp.com/dashboard/builds'
11
- end
12
-
13
- def header_div
14
- @header_div ||= header_divs[bundle_index]
15
- end
16
-
17
- def builds_table
18
- @builds_table ||= header_div.parent.tables[bundle_index]
19
- end
20
-
21
- def builds_table_rows
22
- builds_table.trs(id: /\/dashboard\/builds\/report\/\d+\//)
23
- end
24
-
25
- def next_page
26
- link = next_page_link
27
- return false unless link
28
- link.click
29
- true
30
- end
31
-
32
- def more_builds_link
33
- builds_table.as(text: 'more')[0]
34
- end
35
-
36
- def more_builds
37
- link = more_builds_link
38
- return unless link
39
- link.click
40
- sleep 2
41
- end
42
-
43
- private
44
-
45
- def next_page_link
46
- links = builds_table.as(title: 'Next Page')
47
- links.length == 1 ? links[0] : nil
48
- end
49
-
50
- def header_divs
51
- @header_divs ||= b.divs(class: 'section-header-build')
52
- end
53
-
54
- def bundle_index
55
- @bundle_index ||= header_divs.to_a.index { |div| div.li.text == @bundle_id }
56
- end
57
-
58
- def b
59
- @browser
60
- end
61
-
62
- end
63
- end