capture_page 1.0.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +160 -0
- data/lib/capture.rb +113 -0
- metadata +47 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 4c0646db848b7f2468b5115caed1a2101188c86f3e2fe7764eb84cb155003df1
|
|
4
|
+
data.tar.gz: 77cb86e03ebaa2692a1c186ed9b3540c8e6600ab49f74732eb1bf9e732a23358
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f7070bb1dc03c587dd27f0f76dc7bb4a22fdd694707ef3026069248d11a72648c2c77139cfcf0c463423593695388415965c12066850dea2141f22c40e445909
|
|
7
|
+
data.tar.gz: 7aa49e640f95945ad92e9de26319769b76b148c518333d636fb0957330e846b0ec50de4b8bf2c9166be8bc819d1d6f35b6399a41c0bf3349fd3143a34b29e383
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Techulus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Capture Ruby SDK
|
|
2
|
+
|
|
3
|
+
Official Ruby SDK for [Capture](https://capture.page) - Screenshot and content extraction API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add to your Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem "capture_page"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or install directly:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
gem install capture_page
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
require "capture"
|
|
23
|
+
|
|
24
|
+
client = Capture.new("your-api-key", "your-api-secret")
|
|
25
|
+
|
|
26
|
+
image_url = client.build_image_url("https://example.com")
|
|
27
|
+
puts image_url
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Features
|
|
31
|
+
|
|
32
|
+
- **Screenshot Capture**: Capture full-page or viewport screenshots as PNG/JPG
|
|
33
|
+
- **PDF Generation**: Convert web pages to PDF documents
|
|
34
|
+
- **Content Extraction**: Extract HTML and text content from web pages
|
|
35
|
+
- **Metadata Extraction**: Get page metadata (title, description, og tags, etc.)
|
|
36
|
+
- **Animated GIFs**: Create animated GIFs of page interactions
|
|
37
|
+
- **Zero Dependencies**: Uses only Ruby standard library
|
|
38
|
+
|
|
39
|
+
## Usage
|
|
40
|
+
|
|
41
|
+
### Initialize the Client
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
require "capture"
|
|
45
|
+
|
|
46
|
+
client = Capture.new("your-api-key", "your-api-secret")
|
|
47
|
+
|
|
48
|
+
# Use edge endpoint for faster response times
|
|
49
|
+
client = Capture.new("your-api-key", "your-api-secret", use_edge: true)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Building URLs
|
|
53
|
+
|
|
54
|
+
#### Image Capture
|
|
55
|
+
|
|
56
|
+
```ruby
|
|
57
|
+
image_url = client.build_image_url("https://example.com")
|
|
58
|
+
|
|
59
|
+
image_url = client.build_image_url("https://example.com", {
|
|
60
|
+
"full" => true,
|
|
61
|
+
"delay" => 2,
|
|
62
|
+
"vw" => 1920,
|
|
63
|
+
"vh" => 1080
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
#### PDF Capture
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
pdf_url = client.build_pdf_url("https://example.com")
|
|
71
|
+
|
|
72
|
+
pdf_url = client.build_pdf_url("https://example.com", {
|
|
73
|
+
"format" => "A4",
|
|
74
|
+
"landscape" => true
|
|
75
|
+
})
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Content Extraction
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
content_url = client.build_content_url("https://example.com")
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### Metadata Extraction
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
metadata_url = client.build_metadata_url("https://example.com")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### Animated GIF
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
animated_url = client.build_animated_url("https://example.com")
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Fetching Data
|
|
97
|
+
|
|
98
|
+
#### Fetch Image
|
|
99
|
+
|
|
100
|
+
```ruby
|
|
101
|
+
image_data = client.fetch_image("https://example.com")
|
|
102
|
+
File.binwrite("screenshot.png", image_data)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### Fetch PDF
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
pdf_data = client.fetch_pdf("https://example.com", { "full" => true })
|
|
109
|
+
File.binwrite("page.pdf", pdf_data)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Fetch Content
|
|
113
|
+
|
|
114
|
+
```ruby
|
|
115
|
+
content = client.fetch_content("https://example.com")
|
|
116
|
+
puts content["html"]
|
|
117
|
+
puts content["textContent"]
|
|
118
|
+
puts content["markdown"]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
#### Fetch Metadata
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
metadata = client.fetch_metadata("https://example.com")
|
|
125
|
+
puts metadata["metadata"]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### Fetch Animated GIF
|
|
129
|
+
|
|
130
|
+
```ruby
|
|
131
|
+
gif_data = client.fetch_animated("https://example.com")
|
|
132
|
+
File.binwrite("animation.gif", gif_data)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Configuration Options
|
|
136
|
+
|
|
137
|
+
### Constructor Options
|
|
138
|
+
|
|
139
|
+
- `use_edge` (boolean): Use edge.capture.page instead of cdn.capture.page for faster response times
|
|
140
|
+
|
|
141
|
+
## API Endpoints
|
|
142
|
+
|
|
143
|
+
The SDK supports two base URLs:
|
|
144
|
+
|
|
145
|
+
- **CDN**: `https://cdn.capture.page` (default)
|
|
146
|
+
- **Edge**: `https://edge.capture.page` (when `use_edge: true`)
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT
|
|
151
|
+
|
|
152
|
+
## Links
|
|
153
|
+
|
|
154
|
+
- [Website](https://capture.page)
|
|
155
|
+
- [Documentation](https://docs.capture.page)
|
|
156
|
+
- [GitHub](https://github.com/techulus/capture-ruby)
|
|
157
|
+
|
|
158
|
+
## Support
|
|
159
|
+
|
|
160
|
+
For support, please visit [capture.page](https://capture.page) or open an issue on GitHub.
|
data/lib/capture.rb
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "digest/md5"
|
|
4
|
+
require "net/http"
|
|
5
|
+
require "uri"
|
|
6
|
+
require "json"
|
|
7
|
+
|
|
8
|
+
class Capture
|
|
9
|
+
API_URL = "https://cdn.capture.page"
|
|
10
|
+
EDGE_URL = "https://edge.capture.page"
|
|
11
|
+
|
|
12
|
+
attr_reader :key, :options
|
|
13
|
+
|
|
14
|
+
def initialize(key, secret, options = {})
|
|
15
|
+
@key = key
|
|
16
|
+
@secret = secret
|
|
17
|
+
options = options.nil? ? {} : options
|
|
18
|
+
raise TypeError, "options must be a Hash" unless options.is_a?(Hash)
|
|
19
|
+
@options = options
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def build_image_url(url, options = {})
|
|
23
|
+
build_url(url, "image", options)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def build_pdf_url(url, options = {})
|
|
27
|
+
build_url(url, "pdf", options)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def build_content_url(url, options = {})
|
|
31
|
+
build_url(url, "content", options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def build_metadata_url(url, options = {})
|
|
35
|
+
build_url(url, "metadata", options)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def build_animated_url(url, options = {})
|
|
39
|
+
build_url(url, "animated", options)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def fetch_image(url, options = {})
|
|
43
|
+
fetch_binary(build_image_url(url, options))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def fetch_pdf(url, options = {})
|
|
47
|
+
fetch_binary(build_pdf_url(url, options))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def fetch_content(url, options = {})
|
|
51
|
+
fetch_json(build_content_url(url, options))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def fetch_metadata(url, options = {})
|
|
55
|
+
fetch_json(build_metadata_url(url, options))
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def fetch_animated(url, options = {})
|
|
59
|
+
fetch_binary(build_animated_url(url, options))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
def build_url(url, request_type, options)
|
|
65
|
+
raise TypeError, "key and secret must be strings" unless @key.is_a?(String) && @secret.is_a?(String)
|
|
66
|
+
raise ArgumentError, "Key and Secret is required" if @key.empty? || @secret.empty?
|
|
67
|
+
raise ArgumentError, "url is required" if url.nil? || (url.is_a?(String) && url.empty?)
|
|
68
|
+
raise TypeError, "url should be of type string (something like www.google.com)" unless url.is_a?(String)
|
|
69
|
+
|
|
70
|
+
options = options.nil? ? {} : options
|
|
71
|
+
raise TypeError, "options must be a Hash" unless options.is_a?(Hash)
|
|
72
|
+
params = options.merge("url" => url)
|
|
73
|
+
query_string = encode_query_string(params)
|
|
74
|
+
token = generate_token(@secret, query_string)
|
|
75
|
+
base_url = @options[:use_edge] || @options["useEdge"] ? EDGE_URL : API_URL
|
|
76
|
+
|
|
77
|
+
"#{base_url}/#{@key}/#{token}/#{request_type}?#{query_string}"
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def generate_token(secret, query_string)
|
|
81
|
+
Digest::MD5.hexdigest("#{secret}#{query_string}")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def encode_query_string(params)
|
|
85
|
+
filtered = params.each_with_object({}) do |(k, v), hash|
|
|
86
|
+
next if v.nil?
|
|
87
|
+
|
|
88
|
+
hash[k] = case v
|
|
89
|
+
when true then "true"
|
|
90
|
+
when false then "false"
|
|
91
|
+
else v.to_s
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
URI.encode_www_form(filtered)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def fetch_binary(url)
|
|
99
|
+
uri = URI.parse(url)
|
|
100
|
+
response = Net::HTTP.get_response(uri)
|
|
101
|
+
raise "HTTP Error: #{response.code} #{response.message}" unless response.is_a?(Net::HTTPSuccess)
|
|
102
|
+
|
|
103
|
+
response.body.force_encoding("BINARY")
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def fetch_json(url)
|
|
107
|
+
uri = URI.parse(url)
|
|
108
|
+
response = Net::HTTP.get_response(uri)
|
|
109
|
+
raise "HTTP Error: #{response.code} #{response.message}" unless response.is_a?(Net::HTTPSuccess)
|
|
110
|
+
|
|
111
|
+
JSON.parse(response.body)
|
|
112
|
+
end
|
|
113
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: capture_page
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Capture Team
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Official Ruby SDK for Capture (capture.page). Capture screenshots, generate
|
|
13
|
+
PDFs, extract content and metadata from web pages.
|
|
14
|
+
email:
|
|
15
|
+
- support@capture.page
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- LICENSE
|
|
21
|
+
- README.md
|
|
22
|
+
- lib/capture.rb
|
|
23
|
+
homepage: https://capture.page
|
|
24
|
+
licenses:
|
|
25
|
+
- MIT
|
|
26
|
+
metadata:
|
|
27
|
+
homepage_uri: https://capture.page
|
|
28
|
+
source_code_uri: https://github.com/techulus/capture-ruby
|
|
29
|
+
documentation_uri: https://docs.capture.page
|
|
30
|
+
rdoc_options: []
|
|
31
|
+
require_paths:
|
|
32
|
+
- lib
|
|
33
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
34
|
+
requirements:
|
|
35
|
+
- - ">="
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '3.1'
|
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
43
|
+
requirements: []
|
|
44
|
+
rubygems_version: 4.0.6
|
|
45
|
+
specification_version: 4
|
|
46
|
+
summary: Ruby SDK for Capture - Screenshot and content extraction API
|
|
47
|
+
test_files: []
|