howlongtobeat 0.1.2 → 0.2.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 +4 -4
- data/CHANGELOG.md +16 -7
- data/README.md +38 -10
- data/lib/howlongtobeat/html_requests.rb +18 -20
- data/lib/howlongtobeat/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dade03f5e29eecc43b780f4721d6843fee4033a1a5d374ad65adbfcf9510cd21
|
|
4
|
+
data.tar.gz: 51ce4b254c4f8c8923ba56b5dacb97e8981437b449de4285c7e29f1856aa111e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9fb70b3b35d2a6465f37a063f2c34338dd82284ccc1e0aa684361d0a28d8028a129db8b1ea653f66fd24f9f4206284f835c5dce3f02d32e47ff3b2158b1f50ec
|
|
7
|
+
data.tar.gz: b90d809192fd9b481c837f75c53684dca44b788dcf6fbe2aaa4558203e891fb958e3e018d1e5a69b2c521cd62ede9af314539714f27c39de4f837222b0231d15
|
data/CHANGELOG.md
CHANGED
|
@@ -8,11 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
10
|
### Added
|
|
11
|
-
-
|
|
12
|
-
- Basic search functionality
|
|
13
|
-
- Search by ID functionality
|
|
14
|
-
- Search modifiers support
|
|
15
|
-
- Similarity filtering
|
|
11
|
+
- None
|
|
16
12
|
|
|
17
13
|
### Changed
|
|
18
14
|
- None
|
|
@@ -29,10 +25,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
29
25
|
### Security
|
|
30
26
|
- None
|
|
31
27
|
|
|
32
|
-
## [0.
|
|
28
|
+
## [0.2.0] - 2025-12-13
|
|
33
29
|
|
|
34
|
-
|
|
30
|
+
### Changed
|
|
31
|
+
- Updated authentication to use token-based API (`/api/search/init`)
|
|
32
|
+
- Improved request headers to match API requirements
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- Fixed search functionality to work with HowLongToBeat.com's updated API
|
|
35
36
|
|
|
36
37
|
## [0.1.2] - 2025-03-06
|
|
37
38
|
|
|
38
39
|
- Update Ruby requirement version
|
|
40
|
+
|
|
41
|
+
## [0.1.0] - 2025-03-06
|
|
42
|
+
|
|
43
|
+
- Initial release
|
|
44
|
+
- Basic search functionality
|
|
45
|
+
- Search by ID functionality
|
|
46
|
+
- Search modifiers support
|
|
47
|
+
- Similarity filtering
|
data/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# HowLongToBeat Ruby API
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
A simple Ruby API to read data from howlongtobeat.com.
|
|
4
6
|
|
|
5
7
|
It is inspired by [ScrappyCocco's HowLongToBeat Python API](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI).
|
|
@@ -35,15 +37,37 @@ results = hltb.search("The Witcher 3")
|
|
|
35
37
|
|
|
36
38
|
The `search` method returns an array of possible games, or `nil` if no results were found or there was an error in the request.
|
|
37
39
|
|
|
38
|
-
Each result is
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- `
|
|
42
|
-
- `
|
|
43
|
-
- `
|
|
44
|
-
- `
|
|
45
|
-
- `
|
|
46
|
-
- `
|
|
40
|
+
Each result is an [`HowLongToBeatEntry`](https://github.com/dpashutskii/howlongtobeat/blob/main/lib/howlongtobeat/how_long_to_beat_entry.rb) object containing:
|
|
41
|
+
|
|
42
|
+
#### Base Game Details
|
|
43
|
+
- `game_id`: The game's ID on HowLongToBeat (Integer)
|
|
44
|
+
- `game_name`: The game's name (String)
|
|
45
|
+
- `game_alias`: Alternative names for the game (String)
|
|
46
|
+
- `game_type`: Type of content (e.g., "game", "dlc") (String)
|
|
47
|
+
- `game_image_url`: URL to the game's cover image (String)
|
|
48
|
+
- `game_web_link`: URL to the game's HowLongToBeat page (String)
|
|
49
|
+
- `review_score`: User review score (Integer, 0-100)
|
|
50
|
+
- `profile_dev`: Developer information (String)
|
|
51
|
+
- `profile_platforms`: Available platforms (Array of Strings)
|
|
52
|
+
- `release_world`: Release year (Integer)
|
|
53
|
+
|
|
54
|
+
#### Completion Times (all in hours)
|
|
55
|
+
- `main_story`: Main story completion time (Float)
|
|
56
|
+
- `main_extra`: Main story + side quests completion time (Float)
|
|
57
|
+
- `completionist`: 100% completion time (Float)
|
|
58
|
+
- `all_styles`: Average time across all playstyles (Float)
|
|
59
|
+
- `coop_time`: Co-op gameplay time (Float)
|
|
60
|
+
- `mp_time`: Multiplayer gameplay time (Float)
|
|
61
|
+
|
|
62
|
+
#### Complexity Flags
|
|
63
|
+
- `complexity_lvl_combine`: Combined gameplay complexity (Boolean)
|
|
64
|
+
- `complexity_lvl_sp`: Single-player complexity (Boolean)
|
|
65
|
+
- `complexity_lvl_co`: Co-op complexity (Boolean)
|
|
66
|
+
- `complexity_lvl_mp`: Multiplayer complexity (Boolean)
|
|
67
|
+
|
|
68
|
+
#### Other
|
|
69
|
+
- `similarity`: How closely the game name matches the search query (Float, 0.0 to 1.0)
|
|
70
|
+
- `json_content`: Raw JSON data from the API (Hash)
|
|
47
71
|
|
|
48
72
|
### Search by ID
|
|
49
73
|
|
|
@@ -53,7 +77,7 @@ You can also search for a game using its HowLongToBeat ID:
|
|
|
53
77
|
result = hltb.search_from_id(10270) # The Witcher 3: Wild Hunt
|
|
54
78
|
```
|
|
55
79
|
|
|
56
|
-
This returns a single `
|
|
80
|
+
This returns a single [`HowLongToBeatEntry`](https://github.com/dpashutskii/howlongtobeat/blob/main/lib/howlongtobeat/how_long_to_beat_entry.rb) object or `nil` if not found.
|
|
57
81
|
|
|
58
82
|
### Search Modifiers
|
|
59
83
|
|
|
@@ -85,6 +109,10 @@ hltb = HowLongToBeat::HowLongToBeat.new(0.7)
|
|
|
85
109
|
results = hltb.search("The Witcher 3")
|
|
86
110
|
```
|
|
87
111
|
|
|
112
|
+
## Who's Using It
|
|
113
|
+
|
|
114
|
+
This gem was originally created for and is being used by [SearchToPlay](https://searchtoplay.com), a platform that helps gamers discover and track their gaming journey.
|
|
115
|
+
|
|
88
116
|
## Development
|
|
89
117
|
|
|
90
118
|
After checking out the repo, run `bundle install` to install dependencies. Then, run `rake test` to run the tests.
|
|
@@ -66,7 +66,8 @@ module HowLongToBeat
|
|
|
66
66
|
'content-type' => 'application/json',
|
|
67
67
|
'accept' => '*/*',
|
|
68
68
|
'User-Agent' => random_user_agent,
|
|
69
|
-
'referer' => REFERER_HEADER
|
|
69
|
+
'referer' => REFERER_HEADER,
|
|
70
|
+
'origin' => BASE_URL
|
|
70
71
|
}
|
|
71
72
|
end
|
|
72
73
|
|
|
@@ -116,27 +117,12 @@ module HowLongToBeat
|
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
def send_web_request(game_name, search_modifiers = SearchModifiers::NONE, page = 1)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
search_info ||= send_website_request_getcode(true)
|
|
122
|
-
|
|
123
|
-
return nil unless search_info&.api_key
|
|
124
|
-
|
|
125
|
-
if search_info.search_url
|
|
126
|
-
search_url = "#{BASE_URL}/#{search_info.search_url}"
|
|
127
|
-
else
|
|
128
|
-
search_url = SEARCH_URL
|
|
129
|
-
end
|
|
120
|
+
token = fetch_search_token
|
|
121
|
+
return nil unless token
|
|
130
122
|
|
|
131
|
-
|
|
132
|
-
search_url_with_key = "#{search_url}/#{search_info.api_key}"
|
|
123
|
+
headers = get_search_request_headers.merge('x-auth-token' => token)
|
|
133
124
|
payload = get_search_request_data(game_name, search_modifiers, page)
|
|
134
|
-
|
|
135
|
-
return response if response
|
|
136
|
-
|
|
137
|
-
# Fallback to standard search with API key in payload
|
|
138
|
-
payload = get_search_request_data(game_name, search_modifiers, page, search_info)
|
|
139
|
-
make_request(search_url, headers, payload)
|
|
125
|
+
make_request(SEARCH_URL, headers, payload)
|
|
140
126
|
end
|
|
141
127
|
|
|
142
128
|
def get_game_title(game_id)
|
|
@@ -156,6 +142,18 @@ module HowLongToBeat
|
|
|
156
142
|
|
|
157
143
|
private
|
|
158
144
|
|
|
145
|
+
def fetch_search_token
|
|
146
|
+
url = "#{BASE_URL}/api/search/init?t=#{Time.now.to_i}"
|
|
147
|
+
headers = get_title_request_headers
|
|
148
|
+
response = make_get_request(url, headers)
|
|
149
|
+
return nil unless response
|
|
150
|
+
|
|
151
|
+
json = JSON.parse(response) rescue nil
|
|
152
|
+
json.is_a?(Hash) ? json['token'] : nil
|
|
153
|
+
rescue StandardError
|
|
154
|
+
nil
|
|
155
|
+
end
|
|
156
|
+
|
|
159
157
|
def send_website_request_getcode(parse_all_scripts)
|
|
160
158
|
headers = get_title_request_headers
|
|
161
159
|
response = make_get_request(BASE_URL, headers)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: howlongtobeat
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitrii Pashutskii
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-12-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: nokogiri
|
|
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
120
120
|
- !ruby/object:Gem::Version
|
|
121
121
|
version: '0'
|
|
122
122
|
requirements: []
|
|
123
|
-
rubygems_version: 3.5.
|
|
123
|
+
rubygems_version: 3.5.22
|
|
124
124
|
signing_key:
|
|
125
125
|
specification_version: 4
|
|
126
126
|
summary: Ruby client for HowLongToBeat.com
|