tf2r 0.3.1 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0228ccd1fe398e24c3437a9130d1bb8c60354f2
4
- data.tar.gz: 1d574edad3dfbc811e332ece10e40c8faaa37343
3
+ metadata.gz: d040ee6e9265eed2195362f8c115193590c62207
4
+ data.tar.gz: be7f1f7cf1a805e4fa5b16fc02fd41b0692193c7
5
5
  SHA512:
6
- metadata.gz: 5986819d3cde531f50cd27aebf7aab9d5743f2fe770cfb29f6e27b6e79f9e44282b3396e9d70fc6bf7068f1832ea20856565c01621bc29f64e045429c2a24027
7
- data.tar.gz: 40f6ab0a5eb7dc46dac07043d59de61308a188e22d76b053437f1b16f0a448d5a697f35322bc0666c8ea2bcbae38b2e551a6d370c731c7972994061e51d6a5b1
6
+ metadata.gz: 51aef9d710a7e17129106d3ec3f0843f822cd7e43e5a89e39de7fa48f324877437028fc0f75a3e6a4b7c946d5085dd7a7e4eb721305c0ca5e06bb4fcb134a068
7
+ data.tar.gz: 00ea3e40215556e898e0a9e3c078bab6506083e4f11cac1ca4ee4eb97e36688e7c85ef988586b576fc065130f531a0e39e0a49a760dbba45b02c7b9113b66033
@@ -0,0 +1 @@
1
+ service_name: travis-ci
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tf2r (0.3.1)
4
+ tf2r (0.4.0)
5
5
  mechanize (~> 2.7)
6
6
 
7
7
  GEM
@@ -1,7 +1,7 @@
1
1
  module TF2R
2
2
  # This class handles interaction with TF2R's "API", which is really just an
3
3
  # open endpoint located at http://tf2r.com/job.php, in use all over the site
4
- # to have dynamically updating pages.
4
+ # for dynamically updating pages.
5
5
  class API
6
6
  HOST = 'http://tf2r.com'
7
7
  ENDPOINT = '/job.php'
@@ -9,6 +9,22 @@ module TF2R
9
9
  # a problem for any raffles with a maximum entries greater than 2500.
10
10
  MAX_ENTRY_RESPONSE_COUNT = 2500
11
11
 
12
+ # Queries the API for information about a raffle.
13
+ #
14
+ # @params link_snippet [String] the link snippet of the desired raffle.
15
+ # @return [Array] the API response for the raffle.
16
+ # * ended (+Boolean+) whether the raffle is done.
17
+ # * timeleft (+Fixnum+) seconds remaining.
18
+ # * max_entry (+Fixnum+) maximum number of entries.
19
+ # * entry (+String+) but really a number. This is the ID in TF2R's db of
20
+ # the last entry returned in the response.
21
+ # * wc (+Float+) the chance for any one participant to win.
22
+ # * cur_entry (+Fixnum+) current number of entries.
23
+ # * started (+Boolean+) whether the raffle has begun.
24
+ # * newentry (+Array+) contains hashes representing participants in
25
+ # chronological order.
26
+ # * chaten (+Array+) I have no idea.
27
+ # * chatmax (+Fixnum) ¯\_(ツ)_/¯
12
28
  def self.raffle_info(link_snippet)
13
29
  params = {checkraffle: true, rid: link_snippet[1..-1],
14
30
  lastentrys: 0, lastchat: 0}
@@ -17,7 +33,8 @@ module TF2R
17
33
 
18
34
  private
19
35
 
20
- # TODO: Make this sane with something like httparty
36
+ # Submits a request to job.php with the given params.
37
+ # TODO: should this do something with the responses headers?
21
38
  def self.request(params)
22
39
  uri = URI.parse(HOST)
23
40
  http = Net::HTTP.new(uri.host, uri.port)
@@ -15,6 +15,34 @@ module TF2R
15
15
  get_full_participants if max_entries > API::MAX_ENTRY_RESPONSE_COUNT
16
16
  end
17
17
 
18
+
19
+ # Gives information about the raffle.
20
+ #
21
+ # @example
22
+ # r = Raffle.new('kstzcbd')
23
+ # r.info #=>
24
+ # {:link_snippet=>"kstzcbd",
25
+ # :title=>"Just one refined [1 hour]",
26
+ # :description=>"Plain and simple.",
27
+ # :start_time=>2012-10-29 09:51:45 -0400,
28
+ # :end_time=>2012-10-29 09:53:01 -0400,
29
+ # :win_chance=>0.1,
30
+ # :current_entries=>10,
31
+ # :max_entries=>10,
32
+ # :is_done=>true}
33
+ #
34
+ # @param page [Mechanize::Page] the raffle page.
35
+ # @return [Hash] a representation of the raffle.
36
+ # * :link_snippet (+String+) — the "raffle id" in the URL.
37
+ # * :title (+String+) — the raffle's title.
38
+ # * :description (+String+) — the raffle's "message".
39
+ # * :start_time (+Time+) — the creation time of the raffle.
40
+ # * :end_time (+Time+) — the projects/observed end time for the raffle.
41
+ # * :win_chance (+Float+) — a participant's chance to win the raffle.
42
+ # Rounded to 5 digits.
43
+ # * :current_entries (+Fixnum+) — the current number of participants.
44
+ # * :max_entries (+Fixnum+) — the maximum number of particpants allowed.
45
+ # * :is_done (+Boolean+) — whether new users can enter the raffle.
18
46
  def info
19
47
  @info ||= {link_snippet: @link_snippet, title: title,
20
48
  description: description, start_time: start_time,
@@ -23,6 +51,11 @@ module TF2R
23
51
  is_done: is_done}
24
52
  end
25
53
 
54
+ # Gives information about the raffle's creator.
55
+ #
56
+ # Taken straight from +Scraper+.
57
+ #
58
+ # @see Scraper#scrape_raffle_for_creator
26
59
  def creator
27
60
  @scraper_info[1]
28
61
  end
@@ -38,6 +71,8 @@ module TF2R
38
71
 
39
72
  private
40
73
 
74
+ # Asynchronously makes network connections to TF2R to query its API and
75
+ # scrape the raffle page.
41
76
  def populate_raffle_info
42
77
  threads = []
43
78
  threads << Thread.new do
@@ -56,6 +91,8 @@ module TF2R
56
91
  @full_participants = @scraper.scrape_raffle_for_participants(page)
57
92
  end
58
93
 
94
+ # Converts the representation of participants by TF2R's API into our own
95
+ # standard representation.
59
96
  def normalize_entries(entries)
60
97
  entries.map do |entry|
61
98
  entry[:steam_id] = extract_steam_id entry.delete('link')
@@ -4,6 +4,7 @@ module TF2R
4
4
  include TF2R::TextHelpers
5
5
 
6
6
  class InvalidUserPage < StandardError; end
7
+
7
8
  # Creates a Scraper. Pass values using the options hash.
8
9
  #
9
10
  # :user_agent a String used for the User-Agent header
@@ -207,12 +208,11 @@ module TF2R
207
208
  raise InvalidUserPage, 'The given page does not correspond to any user.'
208
209
  else
209
210
  infos = user_page.parser.css('.raffle_infomation') #sic
210
- avatar_anchor = infos[0].css('img')[0]
211
211
  user_anchor = infos[1].css('a')[0]
212
212
 
213
213
  steam_id = extract_steam_id(user_page.uri.to_s)
214
214
  username = /TF2R Item Raffles - (.+)/.match(user_page.title)[1]
215
- avatar_link = avatar_anchor.attribute('src').to_s
215
+ avatar_link = infos[0].css('img')[0].attribute('src').to_s
216
216
 
217
217
  posrep = infos.css('.upvb').text.to_i
218
218
  negrep = infos.css('.downvb').text.to_i
@@ -1,5 +1,7 @@
1
1
  module TF2R
2
- # TODO: document
2
+ # This module provides common methods for manipulating text throughout this
3
+ # gem. Common operations include messing with Steam ID 64s, hex color codes,
4
+ # and link to resources on TF2R.
3
5
  module TextHelpers
4
6
  # Extracts a hex colour code.
5
7
  #
@@ -43,6 +45,10 @@ module TF2R
43
45
  link = "http://tf2r.com/#{link_snippet}.html"
44
46
  end
45
47
 
48
+ # @example
49
+ # raffle_link_full('kabc123') => 'http://tf2r.com/kabc123.html?full'
50
+ #
51
+ # @see raffle_link
46
52
  def raffle_link_full(link_snippet)
47
53
  "#{raffle_link(link_snippet)}?full"
48
54
  end
@@ -1,3 +1,3 @@
1
1
  module TF2R
2
- VERSION = '0.3.1'
2
+ VERSION = '0.4.0'
3
3
  end
@@ -8,23 +8,56 @@ describe TF2R::Raffle do
8
8
  }
9
9
 
10
10
  describe '#info' do
11
- let(:result) { raffle.info }
11
+ let(:info) { raffle.info }
12
12
 
13
13
  it 'returns correct values' do
14
- expect(result[:link_snippet]).to eql('kstzcbd')
15
- expect(result[:title]).to eql('Just one refined [1 hour]')
16
- expect(result[:description]).to eql('Plain and simple.')
17
- expect(result[:start_time]).to eql(
14
+ expect(info[:link_snippet]).to eql('kstzcbd')
15
+ expect(info[:title]).to eql('Just one refined [1 hour]')
16
+ expect(info[:description]).to eql('Plain and simple.')
17
+ expect(info[:start_time]).to eql(
18
18
  Time.new(2012, 10, 29, 14, 51, 45, '+01:00')
19
19
  )
20
- expect(result[:end_time]).to eql(
20
+ expect(info[:end_time]).to eql(
21
21
  Time.new(2012, 10, 29, 14, 53, 01, '+01:00')
22
22
  )
23
- expect(result[:win_chance]).to eql(0.1)
23
+ expect(info[:win_chance]).to eql(0.1)
24
24
  # TODO: use a raffle where current_entries != max_entries
25
- expect(result[:current_entries]).to eql(10)
26
- expect(result[:max_entries]).to eql(10)
27
- expect(result[:is_done]).to eql(true)
25
+ expect(info[:current_entries]).to eql(10)
26
+ expect(info[:max_entries]).to eql(10)
27
+ expect(info[:is_done]).to eql(true)
28
+ end
29
+ end
30
+
31
+ describe '#creator' do
32
+ let(:creator) { raffle.creator }
33
+
34
+ it 'returns the raffle creator' do
35
+ expect(creator[:steam_id]).to match(76561198061719848)
36
+ expect(creator[:username]).to eql('Yulli')
37
+ expect(creator[:avatar_link]).to match(STEAM_AVATAR_LINK_REGEXP)
38
+ expect(creator[:posrep]).to eql(11459)
39
+ expect(creator[:negrep]).to eql(0)
40
+ expect(creator[:colour]).to match(HEX_COLOUR_REGEXP)
41
+ end
42
+ end
43
+
44
+ describe '#participants' do
45
+ let(:participants) { raffle.participants }
46
+
47
+ it 'returns the correct number of participants' do
48
+ expect(participants.length).to eql(10)
49
+ end
50
+
51
+ it 'returns the correct participants' do
52
+ expect(participants[0][:steam_id]).to match(76561198017461530)
53
+ expect(participants[0][:username]).to eql('TheJohn')
54
+ expect(participants[0][:colour]).to match(HEX_COLOUR_REGEXP)
55
+ expect(participants[0][:avatar_link]).to match(STEAM_AVATAR_LINK_REGEXP)
56
+
57
+ expect(participants[-1][:steam_id]).to match(76561198029274581)
58
+ expect(participants[-1][:username]).to eql('pony danza (OUT...')
59
+ expect(participants[-1][:colour]).to match(HEX_COLOUR_REGEXP)
60
+ expect(participants[-1][:avatar_link]).to match(STEAM_AVATAR_LINK_REGEXP)
28
61
  end
29
62
  end
30
63
  end
@@ -8,12 +8,6 @@ describe TF2R::Scraper do
8
8
  end
9
9
  }
10
10
 
11
- it 'is instantiable' do
12
- expect{
13
- TF2R::Scraper.new()
14
- }.not_to raise_error
15
- end
16
-
17
11
  describe '#new' do
18
12
  context 'no options are given' do
19
13
  it 'creates an agent with default user agent if none is specified' do
@@ -53,51 +47,26 @@ describe TF2R::Scraper do
53
47
  :headers => {'content_type' => 'text/html'})
54
48
  end
55
49
 
56
- it 'makes a request to the specified URL' do
57
- expect(
58
- scraper.fetch('http://google.com')
59
- ).to have_requested(:get, 'google.com')
60
- end
61
-
62
50
  it 'returns a Mechanize::Page' do
63
51
  expect(scraper.fetch('http://google.com')).to be_a(Mechanize::Page)
64
52
  end
65
53
  end
66
54
 
67
- describe '#scrape_raffle' do
68
- let(:result) { scraper.scrape_raffle(raffle_page) }
69
-
70
- it 'returns an Array' do
71
- expect(result).to be_an(Array)
72
- end
73
-
74
- it 'returns the same as its child methods' do
75
- expect(result[0]).to eql(scraper.scrape_raffle_for_raffle(raffle_page))
76
- expect(result[1]).to eql(scraper.scrape_raffle_for_creator(raffle_page))
77
- end
78
- end
79
-
80
55
  describe '#scrape_main_page' do
81
56
  let(:result) {
82
- VCR.use_cassette('raffle_kstzcbd') do
83
- scraper.scrape_main_page
84
- end
57
+ scraper.scrape_main_page
85
58
  }
86
59
 
87
60
  before(:each) do
88
61
  raffles_file = File.new(File.join(File.dirname(__FILE__), 'raffles.html'))
62
+
89
63
  stub_request(:get, "http://tf2r.com/raffles.html").
90
64
  with(:headers => {'Accept'=>'*/*', 'Host'=>'tf2r.com'}).
91
65
  to_return(:status => 200, :body => raffles_file,
92
66
  :headers => {'content_type' => 'text/html'})
93
67
  end
94
68
 
95
- it 'returns an Array of Strings' do
96
- expect(result).to be_an(Array)
97
- expect(result[0]).to be_a(String)
98
- expect(result[-1]).to be_a(String)
99
- end
100
-
69
+ # TODO: figure out a way to periodicially use more recent pages
101
70
  it 'returns raffle links in reverse chronological order' do
102
71
  # See spec/raffles.html for the hard-coded values.
103
72
  expect(result[0]).to eql('http://tf2r.com/kzkp8jo.html')
@@ -105,12 +74,17 @@ describe TF2R::Scraper do
105
74
  end
106
75
  end
107
76
 
108
- describe '#scrape_raffle_for_creator' do
109
- let(:result) { scraper.scrape_raffle_for_creator(raffle_page) }
77
+ describe '#scrape_raffle' do
78
+ let(:result) { scraper.scrape_raffle(raffle_page) }
110
79
 
111
- it 'returns a Hash representation of a user' do
112
- expect(result).to be_a(Hash)
80
+ it 'returns the same as its child methods' do
81
+ expect(result[0]).to eql(scraper.scrape_raffle_for_raffle(raffle_page))
82
+ expect(result[1]).to eql(scraper.scrape_raffle_for_creator(raffle_page))
113
83
  end
84
+ end
85
+
86
+ describe '#scrape_raffle_for_creator' do
87
+ let(:result) { scraper.scrape_raffle_for_creator(raffle_page) }
114
88
 
115
89
  # This is a terrible spec right now. The raffle tested against is one of
116
90
  # my own, which is constantly updated as I use the site. If I gain or lose
@@ -118,13 +92,13 @@ describe TF2R::Scraper do
118
92
  # TODO: Use a stagnant alt account to make a test raffle.
119
93
  it 'returns correct values' do
120
94
  expect(result[:steam_id]).to eql(76561198061719848)
121
- expect(result[:colour]).to eql('70b01b')
95
+ expect(result[:colour]).to match(HEX_COLOUR_REGEXP)
122
96
 
123
97
  # The following expectations are very brittle. TF2R updates the certain
124
98
  # user attributes (such as name and avatar) every time the user logs in
125
99
  # with new ones.
126
100
  expect(result[:username]).to eql('Yulli')
127
- expect(result[:avatar_link]).to eql('http://media.steampowered.com/steamcommunity/public/images/avatars/bc/bc9dc4302d23f2e2f37f59c59f29c27dbc8cade6_full.jpg')
101
+ expect(result[:avatar_link]).to match(STEAM_AVATAR_LINK_REGEXP)
128
102
 
129
103
  # Talk about brittle.
130
104
  expect(result[:posrep]).to eql(11459)
@@ -136,10 +110,6 @@ describe TF2R::Scraper do
136
110
  describe '#scrape_raffle_for_raffle' do
137
111
  let(:result) { scraper.scrape_raffle_for_raffle(raffle_page) }
138
112
 
139
- it 'returns a Hash representation of a raffle' do
140
- expect(result).to be_a(Hash)
141
- end
142
-
143
113
  it 'returns correct values' do
144
114
  expect(result[:link_snippet]).to eql('kstzcbd')
145
115
  expect(result[:title]).to eql('Just one refined [1 hour]')
@@ -154,6 +124,7 @@ describe TF2R::Scraper do
154
124
  end
155
125
 
156
126
  describe '#scrape_raffle_for_participants' do
127
+ # TODO: use a real test raffle
157
128
  let(:page) {
158
129
  VCR.use_cassette('raffle_kstzcbd_full') do
159
130
  scraper.fetch('http://tf2r.com/kstzcbd.html?full')
@@ -161,12 +132,6 @@ describe TF2R::Scraper do
161
132
  }
162
133
  let(:result) { scraper.scrape_raffle_for_participants(page) }
163
134
 
164
- it 'returns an Array of Hashes' do
165
- expect(result).to be_an(Array)
166
- expect(result[0]).to be_a(Hash)
167
- expect(result[-1]).to be_a(Hash)
168
- end
169
-
170
135
  it 'returns correct values' do
171
136
  expect(result[0][:steam_id]).to eql(76561198017461530)
172
137
  expect(result[0][:username]).to eql('TheJohn')
@@ -187,17 +152,13 @@ describe TF2R::Scraper do
187
152
  }
188
153
  let(:result) { scraper.scrape_user(user_page) }
189
154
 
190
- it 'returns a Hash' do
191
- expect(result).to be_a(Hash)
192
- end
193
-
194
155
  # This spec is also brittle. It relies on my TF2R user account, which is
195
156
  # updated constantly.
196
157
  # TODO: use a stagnant alt account
197
158
  it 'returns correct values' do
198
159
  expect(result[:steam_id]).to eql(76561198061719848)
199
160
  expect(result[:username]).to eql('Yulli')
200
- expect(result[:avatar_link]).to eql('http://media.steampowered.com/steamcommunity/public/images/avatars/bc/bc9dc4302d23f2e2f37f59c59f29c27dbc8cade6_full.jpg')
161
+ expect(result[:avatar_link]).to match(STEAM_AVATAR_LINK_REGEXP)
201
162
  expect(result[:posrep]).to eql(11459)
202
163
  expect(result[:negrep]).to eql(0)
203
164
  expect(result[:colour]).to eql('70b01b')
@@ -228,12 +189,6 @@ describe TF2R::Scraper do
228
189
  }
229
190
  let(:result) { scraper.scrape_ranks(info_page) }
230
191
 
231
- it 'returns an Array of Hashes' do
232
- expect(result).to be_an(Array)
233
- expect(result[0]).to be_a(Hash)
234
- expect(result[-1]).to be_a(Hash)
235
- end
236
-
237
192
  it 'returns correct values' do
238
193
  expect(result[0][:name]).to eql('User')
239
194
  expect(result[0][:description]).to eql(
@@ -242,6 +197,7 @@ describe TF2R::Scraper do
242
197
  expect(result[0][:colour]).to eql('ebe2ca')
243
198
 
244
199
  # This is brittle. Every time a new rank is added, this fails.
200
+ # TODO: explore possibilities to limber this up
245
201
  expect(result[-1][:name]).to eql('Lense')
246
202
  expect(result[-1][:description]).to eql('[ Custom donator rank ]')
247
203
  expect(result[-1][:colour]).to eql('545d6c')
@@ -23,4 +23,7 @@ VCR.configure do |c|
23
23
  end
24
24
  end
25
25
 
26
- WebMock.disable_net_connect!(allow_localhost: true)
26
+ WebMock.disable_net_connect!(allow_localhost: true)
27
+
28
+ STEAM_AVATAR_LINK_REGEXP = /^http:\/\/media\.steampowered\.com\/steamcommunity\/public\/images\/avatars\/\w{2}\/[\w]+\.jpg$/
29
+ HEX_COLOUR_REGEXP = /^[a-f0-9]{3}{1,2}$/i
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tf2r
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Kim
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-18 00:00:00.000000000 Z
11
+ date: 2014-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -143,6 +143,7 @@ executables: []
143
143
  extensions: []
144
144
  extra_rdoc_files: []
145
145
  files:
146
+ - ".coveralls.yml"
146
147
  - ".gitignore"
147
148
  - ".ruby-gemset"
148
149
  - ".ruby-version"