capture_page 1.0.0 → 1.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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -0
  3. data/lib/capture.rb +91 -1
  4. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c0646db848b7f2468b5115caed1a2101188c86f3e2fe7764eb84cb155003df1
4
- data.tar.gz: 77cb86e03ebaa2692a1c186ed9b3540c8e6600ab49f74732eb1bf9e732a23358
3
+ metadata.gz: ede382d29f59a4c71e609f79d74574122e2432a5d145873d8a038f5c4bf850f3
4
+ data.tar.gz: 6ad9064e2506f3bd2bada3d4025d894cf87be551272161627c472dcdf06a40c4
5
5
  SHA512:
6
- metadata.gz: f7070bb1dc03c587dd27f0f76dc7bb4a22fdd694707ef3026069248d11a72648c2c77139cfcf0c463423593695388415965c12066850dea2141f22c40e445909
7
- data.tar.gz: 7aa49e640f95945ad92e9de26319769b76b148c518333d636fb0957330e846b0ec50de4b8bf2c9166be8bc819d1d6f35b6399a41c0bf3349fd3143a34b29e383
6
+ metadata.gz: 2f9ab18049ac143fe3aebd8b9c026705d5708c415743e639c3519b46ae30e6e9ffd4e69bb0af37b434849d350b3b86a407f2139bfa761778e26cc5ef9c99e0a9
7
+ data.tar.gz: c19f5374e91e3d332bc033684dfb25c3409dd8c7c14c199ada926a0f02b0b90fd61bfd58d6092d88b0c556aefdac88a3bba70d4dab656f1dc9cb5dbaa4b520ce
data/README.md CHANGED
@@ -34,6 +34,7 @@ puts image_url
34
34
  - **Content Extraction**: Extract HTML and text content from web pages
35
35
  - **Metadata Extraction**: Get page metadata (title, description, og tags, etc.)
36
36
  - **Animated GIFs**: Create animated GIFs of page interactions
37
+ - **Browser Sessions**: Create stateful browser sessions and run actions
37
38
  - **Zero Dependencies**: Uses only Ruby standard library
38
39
 
39
40
  ## Usage
@@ -132,6 +133,18 @@ gif_data = client.fetch_animated("https://example.com")
132
133
  File.binwrite("animation.gif", gif_data)
133
134
  ```
134
135
 
136
+ ### Browser Sessions
137
+
138
+ ```ruby
139
+ session = client.sessions.create("maxTtlSeconds" => 300)
140
+ session_id = session["session"]["id"]
141
+
142
+ client.sessions.action(session_id, "goto", "url" => "https://example.com")
143
+ screenshot = client.sessions.action(session_id, "screenshot", "fullPage" => true)
144
+
145
+ client.sessions.close(session_id)
146
+ ```
147
+
135
148
  ## Configuration Options
136
149
 
137
150
  ### Constructor Options
data/lib/capture.rb CHANGED
@@ -5,11 +5,50 @@ require "net/http"
5
5
  require "uri"
6
6
  require "json"
7
7
 
8
+ class CaptureSessionsError < StandardError
9
+ attr_reader :status, :body
10
+
11
+ def initialize(status, body)
12
+ message = body.is_a?(Hash) && body["error"].is_a?(String) ? body["error"] : "Capture Sessions API request failed with status #{status}"
13
+ super(message)
14
+ @status = status
15
+ @body = body
16
+ end
17
+ end
18
+
19
+ class CaptureSessions
20
+ def initialize(client)
21
+ @client = client
22
+ end
23
+
24
+ def create(options = {})
25
+ options = options.nil? ? {} : options
26
+ raise TypeError, "options must be a Hash" unless options.is_a?(Hash)
27
+
28
+ @client.send(:sessions_request, "", :post, options)
29
+ end
30
+
31
+ def get(session_id)
32
+ @client.send(:sessions_request, "/#{@client.send(:escape_path, session_id)}", :get)
33
+ end
34
+
35
+ def close(session_id)
36
+ @client.send(:sessions_request, "/#{@client.send(:escape_path, session_id)}", :delete)
37
+ end
38
+
39
+ def action(session_id, action_type, payload = {})
40
+ payload = payload.nil? ? {} : payload
41
+ raise TypeError, "payload must be a Hash" unless payload.is_a?(Hash)
42
+
43
+ @client.send(:sessions_request, "/#{@client.send(:escape_path, session_id)}/actions", :post, "type" => action_type, "payload" => payload)
44
+ end
45
+ end
46
+
8
47
  class Capture
9
48
  API_URL = "https://cdn.capture.page"
10
49
  EDGE_URL = "https://edge.capture.page"
11
50
 
12
- attr_reader :key, :options
51
+ attr_reader :key, :options, :sessions
13
52
 
14
53
  def initialize(key, secret, options = {})
15
54
  @key = key
@@ -17,6 +56,7 @@ class Capture
17
56
  options = options.nil? ? {} : options
18
57
  raise TypeError, "options must be a Hash" unless options.is_a?(Hash)
19
58
  @options = options
59
+ @sessions = CaptureSessions.new(self)
20
60
  end
21
61
 
22
62
  def build_image_url(url, options = {})
@@ -110,4 +150,54 @@ class Capture
110
150
 
111
151
  JSON.parse(response.body)
112
152
  end
153
+
154
+ def sessions_bearer_token
155
+ raise TypeError, "key and secret must be strings" unless @key.is_a?(String) && @secret.is_a?(String)
156
+ raise ArgumentError, "Key and Secret is required" if @key.empty? || @secret.empty?
157
+
158
+ ["#{@key}:#{@secret}"].pack("m0")
159
+ end
160
+
161
+ def session_url(path = "")
162
+ "#{EDGE_URL}/v1/sessions#{path}"
163
+ end
164
+
165
+ def sessions_request(path, method, body = nil)
166
+ uri = URI.parse(session_url(path))
167
+ request = case method
168
+ when :post then Net::HTTP::Post.new(uri)
169
+ when :get then Net::HTTP::Get.new(uri)
170
+ when :delete then Net::HTTP::Delete.new(uri)
171
+ else raise ArgumentError, "unsupported sessions request method"
172
+ end
173
+
174
+ request["Authorization"] = "Bearer #{sessions_bearer_token}"
175
+ unless body.nil?
176
+ request["Content-Type"] = "application/json"
177
+ request.body = JSON.generate(body)
178
+ end
179
+
180
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
181
+ http.request(request)
182
+ end
183
+ response_body = parse_json_response(response.body)
184
+
185
+ raise CaptureSessionsError.new(response.code.to_i, response_body) unless response.is_a?(Net::HTTPSuccess)
186
+
187
+ response_body
188
+ end
189
+
190
+ def parse_json_response(body)
191
+ return {} if body.nil? || body.empty?
192
+
193
+ JSON.parse(body)
194
+ rescue JSON::ParserError
195
+ {}
196
+ end
197
+
198
+ def escape_path(value)
199
+ raise ArgumentError, "session_id is required" if value.nil? || value.to_s.empty?
200
+
201
+ URI.encode_www_form_component(value.to_s)
202
+ end
113
203
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capture_page
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Capture Team