pdfify-client 0.1.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/CHANGELOG.md +28 -0
- data/LICENSE.txt +21 -0
- data/README.md +465 -0
- data/lib/pdfify/client.rb +96 -0
- data/lib/pdfify/configuration.rb +17 -0
- data/lib/pdfify/version.rb +3 -0
- data/lib/pdfify.rb +38 -0
- metadata +110 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 658d0d93dae647bc25b7610eea5314ac06496453fddd0ced2d0e19e5cd497629
|
|
4
|
+
data.tar.gz: d5658389ef7da0b6db2a1121b01997bdf8042bfde084639ad98e50bb54a5f286
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 0f387017b286d41b50a8eeb6ca9c81140d160d46f63199c293547e7a14373f0ccfd73623c73d0a6a6be6d10a3dd222306f9847efed9ca74872c5657c163e3f13
|
|
7
|
+
data.tar.gz: 586a730c20cafc9d274a24a7b4dcdba56812ae086aacc480aabf3e93a7b0cc8c80e9472c68581de885d12a1a26a372ab5f4bc2aa4de69d9494291868902b7e4f
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-01-25
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of PDFify Ruby gem
|
|
12
|
+
- Basic HTML to PDF conversion via PDFify API
|
|
13
|
+
- Configuration support for API key, base URL, and timeout
|
|
14
|
+
- Error handling for common API errors (quota, validation, auth)
|
|
15
|
+
- Support for test/sandbox mode
|
|
16
|
+
- Support for advanced options (profile, css, auto_compat, template_engine)
|
|
17
|
+
- Comprehensive documentation and examples
|
|
18
|
+
- Rails integration examples
|
|
19
|
+
- DocRaptor migration guide
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
- `PDFify.configure` for global configuration
|
|
23
|
+
- `PDFify.convert` convenience method
|
|
24
|
+
- `PDFify::Client` class for instance-based usage
|
|
25
|
+
- Custom error classes for better error handling
|
|
26
|
+
- HTTParty-based HTTP client
|
|
27
|
+
|
|
28
|
+
[0.1.0]: https://github.com/yourusername/pdfify-ruby/releases/tag/v0.1.0
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PDFify
|
|
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,465 @@
|
|
|
1
|
+
# PDFify Ruby Gem
|
|
2
|
+
|
|
3
|
+
Ruby client library for the [PDFify](https://pdfify.example.com) HTML-to-PDF API. A DocRaptor alternative at 50% cheaper pricing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'pdfify'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And then execute:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bundle install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Or install it yourself as:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
gem install pdfify
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
require 'pdfify'
|
|
29
|
+
|
|
30
|
+
# Configure with your API key
|
|
31
|
+
PDFify.configure do |config|
|
|
32
|
+
config.api_key = "pfy_live_xxxxxxxxxx"
|
|
33
|
+
config.base_url = "https://api.pdfify.example.com" # optional
|
|
34
|
+
config.timeout = 60 # optional, default is 60 seconds
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Convert HTML to PDF
|
|
38
|
+
pdf = PDFify.convert(
|
|
39
|
+
html: "<html><body><h1>Hello World!</h1></body></html>"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Save to file
|
|
43
|
+
File.binwrite("output.pdf", pdf)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
### Basic Conversion
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
# Simple HTML conversion
|
|
52
|
+
pdf = PDFify.convert(html: "<h1>Hello!</h1>")
|
|
53
|
+
File.binwrite("hello.pdf", pdf)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Using Client Instance
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
# Create a client instance
|
|
60
|
+
client = PDFify::Client.new
|
|
61
|
+
|
|
62
|
+
# Convert HTML
|
|
63
|
+
pdf = client.convert(
|
|
64
|
+
html: "<html><body>Content here</body></html>"
|
|
65
|
+
)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Test/Sandbox Mode
|
|
69
|
+
|
|
70
|
+
Use `test: true` or `sandbox: true` to generate PDFs without counting against your quota:
|
|
71
|
+
|
|
72
|
+
```ruby
|
|
73
|
+
pdf = PDFify.convert(
|
|
74
|
+
html: "<h1>Test</h1>",
|
|
75
|
+
test: true # doesn't count against quota
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Advanced Options
|
|
80
|
+
|
|
81
|
+
```ruby
|
|
82
|
+
pdf = PDFify.convert(
|
|
83
|
+
html: "<h1>Advanced</h1>",
|
|
84
|
+
profile: "docraptor", # CSS profile compatibility
|
|
85
|
+
css: "body { color: red; }", # Additional CSS
|
|
86
|
+
auto_compat: true, # Auto-detect template engine
|
|
87
|
+
template_engine: "pdfshift" # Specify engine explicitly
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Error Handling
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
begin
|
|
95
|
+
pdf = PDFify.convert(html: "<h1>Test</h1>")
|
|
96
|
+
File.binwrite("output.pdf", pdf)
|
|
97
|
+
rescue PDFify::QuotaExceededError => e
|
|
98
|
+
puts "Quota exceeded: #{e.message}"
|
|
99
|
+
rescue PDFify::ValidationError => e
|
|
100
|
+
puts "Invalid input: #{e.message}"
|
|
101
|
+
rescue PDFify::AuthenticationError => e
|
|
102
|
+
puts "Authentication failed: #{e.message}"
|
|
103
|
+
rescue PDFify::APIError => e
|
|
104
|
+
puts "API error: #{e.message}"
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Available Error Classes
|
|
109
|
+
|
|
110
|
+
- `PDFify::APIError` - Base error class
|
|
111
|
+
- `PDFify::NetworkError` - Connection/network errors
|
|
112
|
+
- `PDFify::AuthenticationError` - Invalid API key
|
|
113
|
+
- `PDFify::ValidationError` - Invalid parameters (400)
|
|
114
|
+
- `PDFify::QuotaExceededError` - Monthly quota exceeded (403)
|
|
115
|
+
- `PDFify::ContentTooLargeError` - HTML content too large (413)
|
|
116
|
+
- `PDFify::ServerError` - Server-side errors (500)
|
|
117
|
+
- `PDFify::ConfigurationError` - Missing/invalid configuration
|
|
118
|
+
|
|
119
|
+
## Configuration
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
PDFify.configure do |config|
|
|
123
|
+
# Required: Your PDFify API key
|
|
124
|
+
config.api_key = "pfy_live_xxxxxxxxxx"
|
|
125
|
+
|
|
126
|
+
# Optional: API base URL (default: https://pdfify.example.com)
|
|
127
|
+
config.base_url = "https://api.pdfify.example.com"
|
|
128
|
+
|
|
129
|
+
# Optional: Request timeout in seconds (default: 60)
|
|
130
|
+
config.timeout = 60
|
|
131
|
+
end
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Environment Variables
|
|
135
|
+
|
|
136
|
+
You can also set the API key via environment variable:
|
|
137
|
+
|
|
138
|
+
```ruby
|
|
139
|
+
PDFify.configure do |config|
|
|
140
|
+
config.api_key = ENV['PDFIFY_API_KEY']
|
|
141
|
+
end
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Integration with Rails
|
|
145
|
+
|
|
146
|
+
### Initializer
|
|
147
|
+
|
|
148
|
+
Create `config/initializers/pdfify.rb`:
|
|
149
|
+
|
|
150
|
+
```ruby
|
|
151
|
+
PDFify.configure do |config|
|
|
152
|
+
config.api_key = Rails.application.credentials.pdfify_api_key
|
|
153
|
+
# Or use ENV: config.api_key = ENV['PDFIFY_API_KEY']
|
|
154
|
+
end
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Controller Example
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
class ReportsController < ApplicationController
|
|
161
|
+
def download_pdf
|
|
162
|
+
html = render_to_string(template: "reports/invoice", layout: "pdf")
|
|
163
|
+
|
|
164
|
+
pdf = PDFify.convert(html: html)
|
|
165
|
+
|
|
166
|
+
send_data pdf,
|
|
167
|
+
type: "application/pdf",
|
|
168
|
+
disposition: "attachment",
|
|
169
|
+
filename: "invoice-#{@invoice.id}.pdf"
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Service Object Example
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
class InvoicePdfGenerator
|
|
178
|
+
def initialize(invoice)
|
|
179
|
+
@invoice = invoice
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def generate
|
|
183
|
+
html = ApplicationController.render(
|
|
184
|
+
template: "invoices/show",
|
|
185
|
+
layout: "pdf",
|
|
186
|
+
assigns: { invoice: @invoice }
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
PDFify.convert(html: html)
|
|
190
|
+
rescue PDFify::APIError => e
|
|
191
|
+
Rails.logger.error "PDF generation failed: #{e.message}"
|
|
192
|
+
raise
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Usage:
|
|
197
|
+
pdf = InvoicePdfGenerator.new(@invoice).generate
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Replacing DocRaptor
|
|
201
|
+
|
|
202
|
+
If you're migrating from DocRaptor, here's a comparison:
|
|
203
|
+
|
|
204
|
+
### DocRaptor:
|
|
205
|
+
```ruby
|
|
206
|
+
DocRaptor.configure do |config|
|
|
207
|
+
config.username = "YOUR_API_KEY"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
docraptor = DocRaptor::DocApi.new
|
|
211
|
+
pdf = docraptor.create_doc(
|
|
212
|
+
document_content: html,
|
|
213
|
+
document_type: "pdf",
|
|
214
|
+
test: true
|
|
215
|
+
)
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### PDFify:
|
|
219
|
+
```ruby
|
|
220
|
+
PDFify.configure do |config|
|
|
221
|
+
config.api_key = "YOUR_API_KEY"
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
pdf = PDFify.convert(
|
|
225
|
+
html: html,
|
|
226
|
+
test: true
|
|
227
|
+
)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
It's that simple! Just swap the gem and update your configuration.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Development & Publishing Guide
|
|
235
|
+
|
|
236
|
+
### Building the Gem Locally
|
|
237
|
+
|
|
238
|
+
Follow these steps to build and test the gem:
|
|
239
|
+
|
|
240
|
+
#### 1. Install Dependencies
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
cd pdfify-ruby
|
|
244
|
+
bundle install
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
#### 2. Build the Gem
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
gem build pdfify.gemspec
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
This creates a `.gem` file like `pdfify-0.1.0.gem`.
|
|
254
|
+
|
|
255
|
+
#### 3. Test Locally (Without Publishing)
|
|
256
|
+
|
|
257
|
+
Install the gem locally to test it:
|
|
258
|
+
|
|
259
|
+
```bash
|
|
260
|
+
gem install ./pdfify-0.1.0.gem
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Or in a Rails app's Gemfile:
|
|
264
|
+
|
|
265
|
+
```ruby
|
|
266
|
+
gem 'pdfify', path: '../pdfify-ruby'
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Then run `bundle install`.
|
|
270
|
+
|
|
271
|
+
#### 4. Test in IRB
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
irb
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```ruby
|
|
278
|
+
require 'pdfify'
|
|
279
|
+
|
|
280
|
+
PDFify.configure do |config|
|
|
281
|
+
config.api_key = "pfy_test_xxxxxxxxxx"
|
|
282
|
+
config.base_url = "http://localhost:3000" # Your local PDFify server
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# Test it
|
|
286
|
+
pdf = PDFify.convert(html: "<h1>Test</h1>", test: true)
|
|
287
|
+
File.binwrite("test.pdf", pdf)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Publishing to RubyGems.org
|
|
291
|
+
|
|
292
|
+
#### Prerequisites
|
|
293
|
+
|
|
294
|
+
1. Create a RubyGems.org account at https://rubygems.org
|
|
295
|
+
2. Get your API key:
|
|
296
|
+
```bash
|
|
297
|
+
curl -u YOUR_USERNAME https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials
|
|
298
|
+
chmod 0600 ~/.gem/credentials
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
#### Step-by-Step Publishing
|
|
302
|
+
|
|
303
|
+
##### 1. Prepare Your Gem
|
|
304
|
+
|
|
305
|
+
Make sure all files are ready:
|
|
306
|
+
- [ ] Update version in `lib/pdfify/version.rb`
|
|
307
|
+
- [ ] Update gemspec with correct author/email/homepage
|
|
308
|
+
- [ ] Create LICENSE.txt (MIT license recommended)
|
|
309
|
+
- [ ] Create CHANGELOG.md documenting changes
|
|
310
|
+
- [ ] Test thoroughly
|
|
311
|
+
|
|
312
|
+
##### 2. Build the Gem
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
gem build pdfify.gemspec
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
##### 3. Push to RubyGems
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
gem push pdfify-0.1.0.gem
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
You'll see output like:
|
|
325
|
+
```
|
|
326
|
+
Pushing gem to https://rubygems.org...
|
|
327
|
+
Successfully registered gem: pdfify (0.1.0)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
##### 4. Verify
|
|
331
|
+
|
|
332
|
+
Visit https://rubygems.org/gems/pdfify to see your published gem!
|
|
333
|
+
|
|
334
|
+
##### 5. Install Anywhere
|
|
335
|
+
|
|
336
|
+
Now anyone can install it:
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
gem install pdfify
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Or in a Gemfile:
|
|
343
|
+
|
|
344
|
+
```ruby
|
|
345
|
+
gem 'pdfify', '~> 0.1.0'
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Publishing Updates
|
|
349
|
+
|
|
350
|
+
When you need to release a new version:
|
|
351
|
+
|
|
352
|
+
1. **Update version** in `lib/pdfify/version.rb`:
|
|
353
|
+
```ruby
|
|
354
|
+
VERSION = "0.2.0"
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
2. **Update CHANGELOG.md** with changes
|
|
358
|
+
|
|
359
|
+
3. **Build and push**:
|
|
360
|
+
```bash
|
|
361
|
+
gem build pdfify.gemspec
|
|
362
|
+
gem push pdfify-0.2.0.gem
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Yanking a Version (Emergency)
|
|
366
|
+
|
|
367
|
+
If you need to unpublish a broken version:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
gem yank pdfify -v 0.1.0
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Best Practices
|
|
374
|
+
|
|
375
|
+
- Use [Semantic Versioning](https://semver.org/): MAJOR.MINOR.PATCH
|
|
376
|
+
- MAJOR: Breaking changes
|
|
377
|
+
- MINOR: New features (backward compatible)
|
|
378
|
+
- PATCH: Bug fixes
|
|
379
|
+
- Always test locally before publishing
|
|
380
|
+
- Keep CHANGELOG.md updated
|
|
381
|
+
- Tag releases in git: `git tag v0.1.0 && git push --tags`
|
|
382
|
+
- Never publish with sensitive data (API keys, passwords)
|
|
383
|
+
|
|
384
|
+
### Setting Up GitHub Repo (Optional but Recommended)
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
cd pdfify-ruby
|
|
388
|
+
git init
|
|
389
|
+
git add .
|
|
390
|
+
git commit -m "Initial commit"
|
|
391
|
+
git remote add origin https://github.com/yourusername/pdfify-ruby.git
|
|
392
|
+
git push -u origin main
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Then update gemspec with correct GitHub URLs.
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Testing
|
|
400
|
+
|
|
401
|
+
Run the test suite (when tests are added):
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
bundle exec rspec
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## API Reference
|
|
410
|
+
|
|
411
|
+
### `PDFify.configure { |config| ... }`
|
|
412
|
+
|
|
413
|
+
Configure the global PDFify settings.
|
|
414
|
+
|
|
415
|
+
**Parameters:**
|
|
416
|
+
- `config.api_key` (String) - Your PDFify API key (required)
|
|
417
|
+
- `config.base_url` (String) - API base URL (optional, default: https://pdfify.example.com)
|
|
418
|
+
- `config.timeout` (Integer) - Request timeout in seconds (optional, default: 60)
|
|
419
|
+
|
|
420
|
+
### `PDFify.convert(html:, **options)`
|
|
421
|
+
|
|
422
|
+
Convert HTML to PDF.
|
|
423
|
+
|
|
424
|
+
**Parameters:**
|
|
425
|
+
- `html` (String) - HTML content to convert (required)
|
|
426
|
+
- `test` (Boolean) - Enable test/sandbox mode (optional)
|
|
427
|
+
- `sandbox` (Boolean) - Alias for `test` (optional)
|
|
428
|
+
- `profile` (String) - CSS profile to use (optional)
|
|
429
|
+
- `css` (String) - Additional CSS to inject (optional)
|
|
430
|
+
- `auto_compat` (Boolean) - Enable auto-compatibility mode (optional)
|
|
431
|
+
- `template_engine` (String) - Specify template engine (optional)
|
|
432
|
+
|
|
433
|
+
**Returns:**
|
|
434
|
+
- (String) Binary PDF data
|
|
435
|
+
|
|
436
|
+
**Raises:**
|
|
437
|
+
- `ArgumentError` if HTML is missing
|
|
438
|
+
- `PDFify::ConfigurationError` if API key is not configured
|
|
439
|
+
- `PDFify::APIError` and subclasses for API errors
|
|
440
|
+
|
|
441
|
+
### `PDFify::Client.new(config = nil)`
|
|
442
|
+
|
|
443
|
+
Create a new client instance.
|
|
444
|
+
|
|
445
|
+
**Parameters:**
|
|
446
|
+
- `config` (PDFify::Configuration) - Custom configuration (optional, uses global config if nil)
|
|
447
|
+
|
|
448
|
+
**Returns:**
|
|
449
|
+
- PDFify::Client instance
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## License
|
|
454
|
+
|
|
455
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
456
|
+
|
|
457
|
+
## Contributing
|
|
458
|
+
|
|
459
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/yourusername/pdfify-ruby.
|
|
460
|
+
|
|
461
|
+
## Support
|
|
462
|
+
|
|
463
|
+
- Documentation: https://pdfify.example.com/docs
|
|
464
|
+
- Email: support@pdfify.example.com
|
|
465
|
+
- GitHub Issues: https://github.com/yourusername/pdfify-ruby/issues
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require 'httparty'
|
|
2
|
+
|
|
3
|
+
module PDFify
|
|
4
|
+
class Client
|
|
5
|
+
include HTTParty
|
|
6
|
+
|
|
7
|
+
def initialize(config = nil)
|
|
8
|
+
@config = config || PDFify.configuration
|
|
9
|
+
@config.validate!
|
|
10
|
+
|
|
11
|
+
self.class.base_uri(@config.base_url)
|
|
12
|
+
self.class.default_timeout(@config.timeout)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Generate a PDF from HTML
|
|
16
|
+
# @param html [String] The HTML content to convert
|
|
17
|
+
# @param options [Hash] Optional parameters
|
|
18
|
+
# @option options [Boolean] :test Enable test/sandbox mode (doesn't count against quota)
|
|
19
|
+
# @option options [Boolean] :sandbox Alias for :test
|
|
20
|
+
# @option options [String] :profile CSS profile to use
|
|
21
|
+
# @option options [String] :css Additional CSS to inject
|
|
22
|
+
# @option options [Boolean] :auto_compat Enable automatic compatibility mode detection
|
|
23
|
+
# @option options [String] :template_engine Specify template engine (docraptor, pdfshift, etc.)
|
|
24
|
+
# @return [String] Binary PDF data
|
|
25
|
+
def convert(html:, **options)
|
|
26
|
+
raise ArgumentError, "HTML content is required" if html.nil? || html.empty?
|
|
27
|
+
|
|
28
|
+
# Build request body
|
|
29
|
+
body = { html: html }
|
|
30
|
+
|
|
31
|
+
# Add optional parameters
|
|
32
|
+
body[:test] = options[:test] if options.key?(:test)
|
|
33
|
+
body[:sandbox] = options[:sandbox] if options.key?(:sandbox)
|
|
34
|
+
body[:profile] = options[:profile] if options.key?(:profile)
|
|
35
|
+
body[:css] = options[:css] if options.key?(:css)
|
|
36
|
+
body[:auto_compat] = options[:auto_compat] if options.key?(:auto_compat)
|
|
37
|
+
body[:template_engine] = options[:template_engine] if options.key?(:template_engine)
|
|
38
|
+
|
|
39
|
+
# Make API request
|
|
40
|
+
response = self.class.post(
|
|
41
|
+
"/api/v1/convert",
|
|
42
|
+
body: body,
|
|
43
|
+
headers: {
|
|
44
|
+
"Authorization" => "Bearer #{@config.api_key}",
|
|
45
|
+
"User-Agent" => "PDFify Ruby Gem v#{PDFify::VERSION}"
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Handle response
|
|
50
|
+
case response.code
|
|
51
|
+
when 200
|
|
52
|
+
response.body # Return binary PDF data
|
|
53
|
+
when 400
|
|
54
|
+
error = parse_error(response)
|
|
55
|
+
raise ValidationError, error
|
|
56
|
+
when 403
|
|
57
|
+
error = parse_error(response)
|
|
58
|
+
raise QuotaExceededError, error
|
|
59
|
+
when 413
|
|
60
|
+
error = parse_error(response)
|
|
61
|
+
raise ContentTooLargeError, error
|
|
62
|
+
when 401
|
|
63
|
+
raise AuthenticationError, "Invalid API key"
|
|
64
|
+
when 500
|
|
65
|
+
error = parse_error(response)
|
|
66
|
+
raise ServerError, error
|
|
67
|
+
else
|
|
68
|
+
raise APIError, "Unexpected response code: #{response.code}"
|
|
69
|
+
end
|
|
70
|
+
rescue HTTParty::Error, Timeout::Error, Errno::ECONNREFUSED => e
|
|
71
|
+
raise NetworkError, "Failed to connect to PDFify API: #{e.message}"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def parse_error(response)
|
|
77
|
+
return "Unknown error" unless response.body
|
|
78
|
+
|
|
79
|
+
begin
|
|
80
|
+
json = JSON.parse(response.body)
|
|
81
|
+
json["error"] || json["message"] || "Unknown error"
|
|
82
|
+
rescue JSON::ParserError
|
|
83
|
+
response.body
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Custom error classes
|
|
89
|
+
class APIError < StandardError; end
|
|
90
|
+
class NetworkError < APIError; end
|
|
91
|
+
class AuthenticationError < APIError; end
|
|
92
|
+
class ValidationError < APIError; end
|
|
93
|
+
class QuotaExceededError < APIError; end
|
|
94
|
+
class ContentTooLargeError < APIError; end
|
|
95
|
+
class ServerError < APIError; end
|
|
96
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module PDFify
|
|
2
|
+
class Configuration
|
|
3
|
+
attr_accessor :api_key, :base_url, :timeout
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@api_key = nil
|
|
7
|
+
@base_url = "https://pdfify.example.com" # Default, can be overridden
|
|
8
|
+
@timeout = 60 # Default timeout in seconds
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def validate!
|
|
12
|
+
raise ConfigurationError, "API key is required" if api_key.nil? || api_key.empty?
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
class ConfigurationError < StandardError; end
|
|
17
|
+
end
|
data/lib/pdfify.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require_relative 'pdfify/version'
|
|
2
|
+
require_relative 'pdfify/configuration'
|
|
3
|
+
require_relative 'pdfify/client'
|
|
4
|
+
|
|
5
|
+
module PDFify
|
|
6
|
+
class << self
|
|
7
|
+
attr_writer :configuration
|
|
8
|
+
|
|
9
|
+
# Get or initialize configuration
|
|
10
|
+
def configuration
|
|
11
|
+
@configuration ||= Configuration.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Configure PDFify with a block
|
|
15
|
+
# @example
|
|
16
|
+
# PDFify.configure do |config|
|
|
17
|
+
# config.api_key = "pfy_live_xxx"
|
|
18
|
+
# config.base_url = "https://pdfify.example.com"
|
|
19
|
+
# end
|
|
20
|
+
def configure
|
|
21
|
+
yield(configuration)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Reset configuration (useful for testing)
|
|
25
|
+
def reset_configuration!
|
|
26
|
+
@configuration = Configuration.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Convenience method to convert HTML without instantiating a client
|
|
30
|
+
# @param html [String] The HTML content to convert
|
|
31
|
+
# @param options [Hash] Optional parameters
|
|
32
|
+
# @return [String] Binary PDF data
|
|
33
|
+
def convert(html:, **options)
|
|
34
|
+
client = Client.new
|
|
35
|
+
client.convert(html: html, **options)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: pdfify-client
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- almokhtar
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-01-25 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: httparty
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.21'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.21'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: bundler
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '2.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '13.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '13.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rspec
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '3.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '3.0'
|
|
69
|
+
description: A simple Ruby gem to convert HTML to PDF using the PDFify API. PDFify
|
|
70
|
+
is a DocRaptor alternative at 50% cheaper pricing.
|
|
71
|
+
email:
|
|
72
|
+
- hey@almokhtar.dev
|
|
73
|
+
executables: []
|
|
74
|
+
extensions: []
|
|
75
|
+
extra_rdoc_files: []
|
|
76
|
+
files:
|
|
77
|
+
- CHANGELOG.md
|
|
78
|
+
- LICENSE.txt
|
|
79
|
+
- README.md
|
|
80
|
+
- lib/pdfify.rb
|
|
81
|
+
- lib/pdfify/client.rb
|
|
82
|
+
- lib/pdfify/configuration.rb
|
|
83
|
+
- lib/pdfify/version.rb
|
|
84
|
+
homepage: https://github.com/yourusername/pdfify-ruby
|
|
85
|
+
licenses:
|
|
86
|
+
- MIT
|
|
87
|
+
metadata:
|
|
88
|
+
homepage_uri: https://github.com/yourusername/pdfify-ruby
|
|
89
|
+
source_code_uri: https://github.com/yourusername/pdfify-ruby
|
|
90
|
+
changelog_uri: https://github.com/yourusername/pdfify-ruby/blob/main/CHANGELOG.md
|
|
91
|
+
post_install_message:
|
|
92
|
+
rdoc_options: []
|
|
93
|
+
require_paths:
|
|
94
|
+
- lib
|
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: 2.6.0
|
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - ">="
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: '0'
|
|
105
|
+
requirements: []
|
|
106
|
+
rubygems_version: 3.5.16
|
|
107
|
+
signing_key:
|
|
108
|
+
specification_version: 4
|
|
109
|
+
summary: Ruby client for PDFify HTML-to-PDF API
|
|
110
|
+
test_files: []
|