rsteamshot 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/README.md +35 -10
  4. data/lib/rsteamshot.rb +14 -0
  5. data/lib/rsteamshot/app.rb +126 -40
  6. data/lib/rsteamshot/configuration.rb +7 -0
  7. data/lib/rsteamshot/screenshot.rb +51 -0
  8. data/lib/rsteamshot/user.rb +23 -6
  9. data/lib/rsteamshot/version.rb +1 -1
  10. data/rsteamshot.gemspec +5 -0
  11. metadata +7 -56
  12. data/docs/README_md.html +0 -233
  13. data/docs/Rsteamshot.html +0 -147
  14. data/docs/Rsteamshot/App.html +0 -466
  15. data/docs/Rsteamshot/App/BadAppsFile.html +0 -106
  16. data/docs/Rsteamshot/Screenshot.html +0 -562
  17. data/docs/Rsteamshot/ScreenshotPage.html +0 -347
  18. data/docs/Rsteamshot/ScreenshotPaginator.html +0 -307
  19. data/docs/Rsteamshot/User.html +0 -309
  20. data/docs/created.rid +0 -9
  21. data/docs/css/fonts.css +0 -167
  22. data/docs/css/rdoc.css +0 -590
  23. data/docs/fonts/Lato-Light.ttf +0 -0
  24. data/docs/fonts/Lato-LightItalic.ttf +0 -0
  25. data/docs/fonts/Lato-Regular.ttf +0 -0
  26. data/docs/fonts/Lato-RegularItalic.ttf +0 -0
  27. data/docs/fonts/SourceCodePro-Bold.ttf +0 -0
  28. data/docs/fonts/SourceCodePro-Regular.ttf +0 -0
  29. data/docs/images/add.png +0 -0
  30. data/docs/images/arrow_up.png +0 -0
  31. data/docs/images/brick.png +0 -0
  32. data/docs/images/brick_link.png +0 -0
  33. data/docs/images/bug.png +0 -0
  34. data/docs/images/bullet_black.png +0 -0
  35. data/docs/images/bullet_toggle_minus.png +0 -0
  36. data/docs/images/bullet_toggle_plus.png +0 -0
  37. data/docs/images/date.png +0 -0
  38. data/docs/images/delete.png +0 -0
  39. data/docs/images/find.png +0 -0
  40. data/docs/images/loadingAnimation.gif +0 -0
  41. data/docs/images/macFFBgHack.png +0 -0
  42. data/docs/images/package.png +0 -0
  43. data/docs/images/page_green.png +0 -0
  44. data/docs/images/page_white_text.png +0 -0
  45. data/docs/images/page_white_width.png +0 -0
  46. data/docs/images/plugin.png +0 -0
  47. data/docs/images/ruby.png +0 -0
  48. data/docs/images/tag_blue.png +0 -0
  49. data/docs/images/tag_green.png +0 -0
  50. data/docs/images/transparent.png +0 -0
  51. data/docs/images/wrench.png +0 -0
  52. data/docs/images/wrench_orange.png +0 -0
  53. data/docs/images/zoom.png +0 -0
  54. data/docs/index.html +0 -242
  55. data/docs/js/darkfish.js +0 -161
  56. data/docs/js/jquery.js +0 -4
  57. data/docs/js/navigation.js +0 -142
  58. data/docs/js/navigation.js.gz +0 -0
  59. data/docs/js/search.js +0 -109
  60. data/docs/js/search_index.js +0 -1
  61. data/docs/js/search_index.js.gz +0 -0
  62. data/docs/js/searcher.js +0 -229
  63. data/docs/js/searcher.js.gz +0 -0
  64. data/docs/table_of_contents.html +0 -179
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90dfdeeddcdf96528bc802b870093361da7f2822
4
- data.tar.gz: 45521a0f3db408209f9c15328034b49fbb3bb8bd
3
+ metadata.gz: d404603632e6df914e39a96d01b81da6f04dee91
4
+ data.tar.gz: e19e08b0e3270260f5a546b2eb5fbee44401478c
5
5
  SHA512:
6
- metadata.gz: 3404ffe22ae4de7ed6f02683e6615d08ee6aab41de51d06e7b6b05f1d2b8ec56ea83c7ab9cd4a01c15bad012db26eb875dcd4cbdd4f26a0481756f2316c62285
7
- data.tar.gz: 8e207fd127e0b851917c5be2ce3ea062018af5d502d362a5b12d2a78e13e3bf01b80ed01b4d45cd2895ec9ee2516e03e15660db0a58f4e173e1c079c9328fcfb
6
+ metadata.gz: b9f83b823cbc2bbce3f1cb090cf137ab9b0ce665dd2b06f366c27bbc73789da71a90f7da711cc306ae357f6b8dd5360428dffc593c34103d65c8bcc6abe5708a
7
+ data.tar.gz: 3019a6ae3d5a7b342a9de5a15605e99aa53217018e2d219f677f5b1d3575e63ce6b4e28b1c10676cd16eb552115a0d5661f68cb44d36e064cb4361ebbf9cd238
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.1.3
4
+
5
+ - Add ability to get an app from a screenshot via the `Rsteamshot::Screenshot#app` method.
6
+ - Specify the path to the Steam apps list file in gem-wide configuration block, instead of passing it into individual methods.
7
+ - Add `Rsteamshot::App#find_by_name` to get the best match for an app based on the provided name. For example, passing "oblivion" will return the app named "The Elder Scrolls IV: Oblivion".
8
+ - Add `Rsteamshot::App#find_by_id` to look up a Steam app by its ID.
9
+ - Add `Rsteamshot::Screenshot#file_size_in_bytes` to get an integer value for how large a screenshot is, in bytes. Thanks [@marcqualie](https://github.com/marcqualie)!
10
+ - Add `Rsteamshot::App#to_h` and `Rsteamshot::App#to_json` to get hash and JSON representations of apps.
11
+ - Remove the need to manually call `Rsteamshot::App#download_apps_list`. It will now automatically be called when `Rsteamshot::App#search` and similar methods are called.
12
+
3
13
  ## 0.1.2
4
14
 
5
15
  Improve the gem description and set the link to its homepage in the gemspec.
data/README.md CHANGED
@@ -6,7 +6,7 @@ Rsteamshot is a Ruby gem for getting screenshots a user has uploaded to their St
6
6
 
7
7
  There's no Steam API that I know of that provides this screenshot data, so this gem works by using [Mechanize](https://github.com/sparklemotion/mechanize) to do web scraping on [steamcommunity.com](http://steamcommunity.com/).
8
8
 
9
- [View source on GitHub](https://github.com/cheshire137/rsteamshot)
9
+ [View source on GitHub](https://github.com/cheshire137/rsteamshot) | [View docs on RubyDoc](http://www.rubydoc.info/gems/rsteamshot/) | [View gem on RubyGems](https://rubygems.org/gems/rsteamshot)
10
10
 
11
11
  ## Installation
12
12
 
@@ -27,27 +27,45 @@ Or install it yourself as:
27
27
  ## Usage
28
28
 
29
29
  ```ruby
30
+ # Specify where the latest list of apps from Steam should be downloaded as a JSON file, and
31
+ # referenced when looking up app IDs:
32
+ Rsteamshot.configure do |config|
33
+ config.apps_list_path = 'apps-list.json'
34
+ end
35
+
30
36
  # Get screenshots uploaded by a Steam user:
31
37
  steam_user_name = 'cheshire137'
32
- user = Rsteamshot::User.new(steam_user_name, per_page: 10)
38
+ user = Rsteamshot::User.new(steam_user_name)
39
+ user.per_page = 10
33
40
  order = 'newestfirst' # also: score, oldestfirst
34
41
  screenshots = user.screenshots(order: order)
35
42
  screenshots += user.screenshots(order: order, page: 2)
36
43
 
37
- # Find a Steam app by name:
38
- apps_path = 'apps-list.json'
39
- Rsteamshot::App.download_apps_list(apps_path)
40
- apps = Rsteamshot::App.search('witcher 3', apps_path)
41
- app = apps.first
44
+ # Search Steam apps by name:
45
+ apps = Rsteamshot::App.search('witcher 3')
46
+ # => [#<Rsteamshot::App:0x007feb28b135f8 @id=292030, @name="The Witcher 3: Wild Hunt"...
47
+ apps.size
48
+ # => 18
49
+
50
+ # Find the best match for a Steam app by name:
51
+ app = Rsteamshot::App.find_by_name('oblivion')
52
+ # => #<Rsteamshot::App:0x007feb25dbd518 @id=22330, @name="The Elder Scrolls IV: Oblivion "...
42
53
 
43
54
  # Filter a user's screenshots to those for a particular app:
44
55
  alice_screenshots = user.screenshots(app_id: '19680')
45
56
 
46
- # Initialize an app directly if you know its ID:
47
- app_id = '377160'
48
- app = Rsteamshot::App.new(id: app_id, per_page: 10)
57
+ # Find a Steam app by its ID:
58
+ app = Rsteamshot::App.find_by_id(377160)
59
+ # => #<Rsteamshot::App:0x007ff800438758 @id=377160, @name="Fallout 4"...
60
+
61
+ # Utility methods for an app:
62
+ app.to_h
63
+ # => {:id=>377160, :name=>"Fallout 4"}
64
+ app.to_json
65
+ # => "{\n \"id\": 377160,\n \"name\": \"Fallout 4\"\n}"
49
66
 
50
67
  # Get screenshots uploaded for a Steam game:
68
+ app.per_page = 10
51
69
  order = 'mostrecent' # also: toprated, trendday, trendweek, trendthreemonths, trendsixmonths,
52
70
  # trendyear
53
71
  screenshots = app.screenshots(order: order)
@@ -82,6 +100,9 @@ screenshots.each do |screenshot|
82
100
  screenshot.file_size
83
101
  # => "0.367 MB"
84
102
 
103
+ screenshot.file_size_in_bytes
104
+ # => 367000
105
+
85
106
  screenshot.width
86
107
  # => 1920
87
108
 
@@ -101,6 +122,10 @@ screenshots.each do |screenshot|
101
122
  screenshot.to_json
102
123
  # => "{\n \"details_url\": \"http://steamcommunity.com/sharedfiles/filedetails/?id=737284878\",
103
124
  end
125
+
126
+ # Force the Steam apps list to be re-downloaded:
127
+ Rsteamshot::App.reset_list
128
+ Rsteamshot::App.download_apps_list
104
129
  ```
105
130
 
106
131
  ## Development
@@ -2,6 +2,7 @@ require 'json'
2
2
  require 'mechanize'
3
3
  require 'open-uri'
4
4
  require 'rsteamshot/app'
5
+ require 'rsteamshot/configuration'
5
6
  require 'rsteamshot/screenshot'
6
7
  require 'rsteamshot/screenshot_page'
7
8
  require 'rsteamshot/screenshot_paginator'
@@ -12,4 +13,17 @@ require 'uri'
12
13
  # Public: Contains classes for finding screenshots uploaded by users to Steam. Screenshots
13
14
  # are from Steam games (apps).
14
15
  module Rsteamshot
16
+ class << self
17
+ attr_writer :configuration
18
+ end
19
+
20
+ def self.configuration
21
+ @configuration ||= Configuration.new
22
+ end
23
+
24
+ # Public: Configure the Rsteamshot gem such as by setting the path to where you have
25
+ # downloaded the list of Steam apps as a JSON file.
26
+ def self.configure
27
+ yield configuration
28
+ end
15
29
  end
@@ -2,10 +2,14 @@ module Rsteamshot
2
2
  # Public: Represents a Steam app, like a video game. Used to fetch the screenshots
3
3
  # that were taken in that app that Steam users have uploaded.
4
4
  class App
5
- # Public: Exception thrown by Rsteamshot::App#search when the given file is not a valid file
6
- # containing Steam apps.
5
+ # Public: Exception thrown when the configured `apps_list_path` is not a valid file containing
6
+ # Steam apps.
7
7
  class BadAppsFile < StandardError; end
8
8
 
9
+ # Public: Exception thrown when there is no file path configured for saving the list of Steam
10
+ # apps, or it is a bad path.
11
+ class BadConfiguration < StandardError; end
12
+
9
13
  # Public: You can fetch this many screenshots at once.
10
14
  MAX_PER_PAGE = 50
11
15
 
@@ -22,53 +26,71 @@ module Rsteamshot
22
26
  # Public: Returns the String name of the Steam app, or nil.
23
27
  attr_reader :name
24
28
 
25
- # Public: Writes a JSON file at the given location with the latest list of apps on Steam.
26
- #
27
- # path - a String file path
29
+ # Public: Returns the number of screenshots that will be fetched per page for this app.
30
+ attr_reader :per_page
31
+
32
+ # Public: Writes a JSON file at the location specified in `Rsteamshot.configuration` with the
33
+ # latest list of apps on Steam. Will be automatically called by #list.
28
34
  #
29
35
  # Returns nothing.
30
- def self.download_apps_list(path)
36
+ def self.download_apps_list
37
+ path = Rsteamshot.configuration.apps_list_path
38
+
39
+ unless path && path.length > 0
40
+ raise BadConfiguration, 'no path configured for JSON apps list from Steam'
41
+ end
42
+
31
43
  File.open(path, 'w') do |file|
32
44
  IO.copy_stream(open(APPS_LIST_URL), file)
33
45
  end
34
46
  end
35
47
 
36
- # Public: Find Steam apps by name.
37
- #
38
- # raw_query - a String search query for an app or game on Steam
39
- # apps_list_path - a String file path to the JSON file produced by #download_apps_list
48
+ # Public: Force the list of Steam apps to be re-downloaded the next time #list is called.
49
+ def self.reset_list
50
+ @@list = nil
51
+ end
52
+
53
+ # Public: Read the JSON file configured in `apps_list_path` and get a list of Steam apps. Will
54
+ # download the latest list of Steam apps to `apps_list_path` if the file does not already exist.
40
55
  #
41
- # Returns an Array of Rsteamshot::Apps.
42
- def self.search(raw_query, apps_list_path)
43
- return [] unless raw_query
56
+ # Returns an Array of Hashes for all the Steam apps.
57
+ def self.list
58
+ @@list ||= begin
59
+ path = Rsteamshot.configuration.apps_list_path
60
+ unless path
61
+ raise BadAppsFile, 'no path configured for JSON apps list from Steam'
62
+ end
44
63
 
45
- unless apps_list_path
46
- raise BadAppsFile, 'no path given to JSON apps list from Steam'
47
- end
64
+ download_apps_list unless File.file?(path)
65
+ raise BadAppsFile, "#{path} is not a file" unless File.file?(path)
48
66
 
49
- unless File.file?(apps_list_path)
50
- raise BadAppsFile, "#{apps_list_path} is not a file"
51
- end
67
+ json = begin
68
+ JSON.parse(File.read(path))
69
+ rescue JSON::ParserError
70
+ raise BadAppsFile, "#{path} is not a valid JSON file"
71
+ end
52
72
 
53
- json = begin
54
- JSON.parse(File.read(apps_list_path))
55
- rescue JSON::ParserError
56
- raise BadAppsFile, "#{apps_list_path} is not a valid JSON file"
57
- end
73
+ applist = json['applist']
74
+ raise BadAppsFile, "#{path} does not have expected JSON format" unless applist
58
75
 
59
- applist = json['applist']
60
- unless applist
61
- raise BadAppsFile, "#{apps_list_path} does not have expected JSON format"
62
- end
76
+ apps = applist['apps']
77
+ raise BadAppsFile, "#{path} does not have expected JSON format" unless apps
63
78
 
64
- apps = applist['apps']
65
- unless apps
66
- raise BadAppsFile, "#{apps_list_path} does not have expected JSON format"
79
+ apps
67
80
  end
81
+ end
82
+
83
+ # Public: Find Steam apps by name.
84
+ #
85
+ # raw_query - a String search query for an app or game on Steam
86
+ #
87
+ # Returns an Array of Rsteamshot::Apps.
88
+ def self.search(raw_query)
89
+ return [] unless raw_query
68
90
 
69
91
  query = raw_query.downcase
70
92
  results = []
71
- apps.each do |data|
93
+ list.each do |data|
72
94
  next unless data['name']
73
95
 
74
96
  if data['name'].downcase.include?(query)
@@ -79,6 +101,34 @@ module Rsteamshot
79
101
  results
80
102
  end
81
103
 
104
+ # Public: Find a Steam app by its name, case insensitive.
105
+ #
106
+ # name - the String name of a game or other app on Steam
107
+ #
108
+ # Returns an Rsteamshot::App or nil.
109
+ def self.find_by_name(name)
110
+ apps = search(name)
111
+ return if apps.length < 1
112
+
113
+ exact_match = apps.detect { |app| app.name.downcase == name }
114
+ return exact_match if exact_match
115
+
116
+ app = apps.shift
117
+ app = apps.shift while app.name.downcase =~ /\btrailer\b/ && apps.length > 0
118
+ app
119
+ end
120
+
121
+ # Public: Find a Steam app by its ID.
122
+ #
123
+ # id - the String or Integer ID of a game or other app on Steam
124
+ #
125
+ # Returns an Rsteamshot::App or nil.
126
+ def self.find_by_id(id)
127
+ id = id.to_i
128
+ app_data = list.detect { |data| data['appid'] == id }
129
+ new(id: app_data['appid'], name: app_data['name']) if app_data
130
+ end
131
+
82
132
  # Public: Initialize a Steam app with the given attributes.
83
133
  #
84
134
  # attrs - the Hash of attributes for this app
@@ -87,15 +137,16 @@ module Rsteamshot
87
137
  # :per_page - how many results to get in each page; defaults to 10; valid range: 1-50;
88
138
  # Integer
89
139
  def initialize(attrs = {})
90
- per_page = attrs.delete(:per_page)
91
-
92
140
  attrs.each { |key, value| instance_variable_set("@#{key}", value) }
141
+ @per_page ||= 10
142
+ initialize_paginator
143
+ end
93
144
 
94
- process_html = ->(html) do
95
- cards_from(html).map { |card| screenshot_from(card) }
96
- end
97
- @paginator = ScreenshotPaginator.new(process_html, max_per_page: MAX_PER_PAGE,
98
- per_page: per_page, steam_per_page: per_page)
145
+ # Public: Check if this App is equivalent to another object.
146
+ #
147
+ # Returns true if the given object represents the same Steam app.
148
+ def ==(other)
149
+ other.class == self.class && other.id == id && other.name == name
99
150
  end
100
151
 
101
152
  # Public: Fetch a list of the newest uploaded screenshots for this app on Steam.
@@ -114,8 +165,42 @@ module Rsteamshot
114
165
  @paginator.screenshots(page: page, url: url)
115
166
  end
116
167
 
168
+ # Public: Get a hash representation of this app.
169
+ #
170
+ # Returns a Hash.
171
+ def to_h
172
+ result = { id: id }
173
+ result[:name] = name if name
174
+ result
175
+ end
176
+
177
+ # Public: Get a JSON representation of this app.
178
+ #
179
+ # Returns a String.
180
+ def to_json
181
+ JSON.pretty_generate(to_h)
182
+ end
183
+
184
+ # Public: Set how many screenshots should be fetched at a time for this app.
185
+ #
186
+ # value - an Integer
187
+ #
188
+ # Returns nothing.
189
+ def per_page=(value)
190
+ @per_page = value
191
+ initialize_paginator
192
+ end
193
+
117
194
  private
118
195
 
196
+ def initialize_paginator
197
+ process_html = ->(html) do
198
+ cards_from(html).map { |card| screenshot_from(card) }
199
+ end
200
+ @paginator = ScreenshotPaginator.new(process_html, max_per_page: MAX_PER_PAGE,
201
+ per_page: per_page, steam_per_page: per_page)
202
+ end
203
+
119
204
  def cards_from(html)
120
205
  html.search('.apphub_Card')
121
206
  end
@@ -135,7 +220,8 @@ module Rsteamshot
135
220
  comment_count = comment_count_from(card)
136
221
  Screenshot.new(details_url: details_url, title: title, medium_url: medium_url,
137
222
  full_size_url: full_size_url, user_name: user_name,
138
- user_url: user_url, like_count: like_count, comment_count: comment_count)
223
+ user_url: user_url, like_count: like_count, comment_count: comment_count,
224
+ app: self)
139
225
  end
140
226
 
141
227
  def urls_from(card)
@@ -0,0 +1,7 @@
1
+ module Rsteamshot
2
+ # Public: Configure the Rsteamshot gem.
3
+ class Configuration
4
+ # Public: The path to a JSON file that will contain Steam app information.
5
+ attr_accessor :apps_list_path
6
+ end
7
+ end
@@ -38,6 +38,9 @@ module Rsteamshot
38
38
  # Public: Returns Integer count of how many comments people have left on this screenshot.
39
39
  attr_reader :comment_count
40
40
 
41
+ # Public: Returns the Rsteamshot::App in which this screenshot was taken.
42
+ attr_reader :app
43
+
41
44
  # Public: Initialize a screenshot with the given attributes.
42
45
  #
43
46
  # attrs - the Hash of attributes for this screenshot
@@ -75,6 +78,7 @@ module Rsteamshot
75
78
  result[:height] = height if height
76
79
  result[:like_count] = like_count if like_count
77
80
  result[:comment_count] = comment_count if comment_count
81
+ result[:app] = app.to_h if app
78
82
  result
79
83
  end
80
84
 
@@ -92,6 +96,21 @@ module Rsteamshot
92
96
  self.class.name + '<' + JSON.generate(to_h) + '>'
93
97
  end
94
98
 
99
+ # Public: file_size parsed into bytes
100
+ #
101
+ # Returns a Integer
102
+ def file_size_in_bytes
103
+ unit_multiplier = 1000
104
+ size, unit = self.file_size.split(' ')
105
+ bytes = case unit.downcase
106
+ when 'kb' then size.to_f * unit_multiplier
107
+ when 'mb' then size.to_f * (unit_multiplier ** 2)
108
+ when 'gb' then size.to_f * (unit_multiplier ** 3)
109
+ else size.to_f
110
+ end
111
+ bytes.to_i
112
+ end
113
+
95
114
  private
96
115
 
97
116
  def has_details?
@@ -113,6 +132,8 @@ module Rsteamshot
113
132
  @user_name = user_name_from(author)
114
133
  @user_url = user_url_from(author)
115
134
 
135
+ @app = app_from(page)
136
+
116
137
  details_block = details_block_from(page)
117
138
  if details_block
118
139
  labels_container = details_block.at('.detailsStatsContainerLeft')
@@ -135,6 +156,36 @@ module Rsteamshot
135
156
  end
136
157
  end
137
158
 
159
+ def app_from(page)
160
+ app_id = app_id_from(page)
161
+ app_name = app_name_from(page)
162
+
163
+ if app_id && app_name
164
+ Rsteamshot::App.new(id: app_id, name: app_name)
165
+ end
166
+ end
167
+
168
+ def app_id_from(page)
169
+ site_info = page.at('.apphub_OtherSiteInfo')
170
+ return unless site_info
171
+
172
+ store_link = site_info.at('a')
173
+ return unless store_link
174
+
175
+ store_url = store_link['href']
176
+ return unless store_url
177
+
178
+ # e.g., "http://store.steampowered.com/app/22330" => "22330"
179
+ store_url.downcase.split('/app/').last
180
+ end
181
+
182
+ def app_name_from(page)
183
+ name_el = page.at('.apphub_AppName')
184
+ return unless name_el
185
+
186
+ name_el.text.strip.gsub(/[[:space:]]\z/, '')
187
+ end
188
+
138
189
  def details_block_from(page)
139
190
  details_blocks = page.search('.rightDetailsBlock')
140
191
  details_blocks.detect do |details_block|