rsteamshot 0.1.2 → 0.1.3

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 (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|