pdfinfo 0.0.2 → 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 +4 -4
- data/.gitignore +1 -0
- data/.rake_tasks~ +5 -0
- data/README.md +45 -12
- data/Rakefile +3 -1
- data/lib/pdfinfo.rb +56 -12
- data/lib/pdfinfo/version.rb +1 -1
- data/lib/tasks/generate_pdf.rake +56 -0
- data/pdfinfo.gemspec +2 -1
- data/spec/fixtures/shell_responses/encrypted.txt +15 -0
- data/spec/fixtures/shell_responses/test.txt +15 -0
- data/spec/pdfinfo_spec.rb +208 -26
- metadata +23 -7
- data/spec/fixtures/shell_response.txt +0 -10
- data/spec/fixtures/test.pdf +0 -127
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c353a570a0806dfe590c8f5f2f13397a065030b0
|
4
|
+
data.tar.gz: 9e09d7118c9006868b586ddce96738ea88a51af1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 777a7cd47cea0d6ebc9d077d5dd3c32f7e89e28de7d11b321d686b1491a04d5c47e5488c14816dd631513d979cb429076c1cb99506a2e356352e6922af5e3ff2
|
7
|
+
data.tar.gz: 13b389f1cdbf9fafab32c811b80faefc7003315e3cb13f5faeb2463decc1bcd4350faf80647afbc2c31698a361d53d73f0d865aca4d0c14d776998586124692d
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Pdfinfo
|
2
2
|
|
3
3
|
Simple ruby wrapper around the pdfinfo command
|
4
|
+
NOTE: This gem is only intended to provide quick access to the metadata returned by the pdfinfo command without flags
|
4
5
|
|
5
6
|
## Depdendecies
|
6
7
|
|
@@ -26,18 +27,35 @@ Or install it yourself as:
|
|
26
27
|
|
27
28
|
|
28
29
|
```ruby
|
29
|
-
pdfinfo
|
30
|
-
|
31
|
-
pdfinfo.
|
32
|
-
pdfinfo.
|
33
|
-
pdfinfo.
|
34
|
-
pdfinfo.
|
35
|
-
|
36
|
-
pdfinfo.
|
37
|
-
pdfinfo.
|
38
|
-
pdfinfo.
|
39
|
-
pdfinfo.
|
40
|
-
pdfinfo.
|
30
|
+
pdfinfo.title #=> "Title" # or nil
|
31
|
+
pdfinfo.subject #=> "Subject" # or nil
|
32
|
+
pdfinfo.keywords #=> ["Keyword1", "Keyword2"] # or nil
|
33
|
+
pdfinfo.author #=> "Author Name" # or nil
|
34
|
+
pdfinfo.creator #=> "Creator Name" # or nil
|
35
|
+
pdfinfo.producer #=> "Producer Name" # or nil
|
36
|
+
ddfinfo.creation_date #=> 2014-10-26 20:50:45 -0700 # Time object
|
37
|
+
pdfinfo.form #=> "none"
|
38
|
+
pdfinfo.page_count #=> 3
|
39
|
+
pdfinfo.width #=> 612
|
40
|
+
pdfinfo.height #=> 792
|
41
|
+
pdfinfo.size #=> 1521 # file size in bytes
|
42
|
+
pdfinfo.pdf_version #=> "1.3"
|
43
|
+
pdfinfo.encrypted? #=> false # or true
|
44
|
+
pdfinfo.usage_rights #=> {print: true, copy: true, change: true, add_notes: true}
|
45
|
+
pdfinfo.printable? #=> true # or false
|
46
|
+
pdfinfo.copyable? #=> true # or false
|
47
|
+
pdfinfo.changeable? #=> true # or false
|
48
|
+
pdfinfo.modifiable? #=> true # or false. alias for #changeable?
|
49
|
+
pdfinfo.annotatable? #=> true # or false
|
50
|
+
pdfinfo.tagged? #=> false # or true
|
51
|
+
```
|
52
|
+
For encrypted files with a password you can pass in the user or owner password as options
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
pdfinfo = Pdfinfo.new("path/to/encrypted.pdf", user_password: 'foo')
|
56
|
+
# pdfinfo = Pdfinfo.new("path/to/encrypted.pdf", owner_password: 'foo')
|
57
|
+
pdfinfo.encrypted? #=> true
|
58
|
+
pdfinfo.usage_rights #=> {print: false, copy: false, change: false, add_notes: false}
|
41
59
|
```
|
42
60
|
|
43
61
|
You can directly set the location of the executable if its not located in your environment $PATH or you just want to point to a different location.
|
@@ -47,6 +65,16 @@ Pdfinfo.pdfinfo_command = '/another/bin/path/pdfinfo'
|
|
47
65
|
Pdfinfo.pdfinfo_command #=> '/another/bin/path/pdfinfo'
|
48
66
|
```
|
49
67
|
|
68
|
+
## Running specs
|
69
|
+
|
70
|
+
generate pdf fixtures by first running
|
71
|
+
|
72
|
+
$ rake generate_fixtures
|
73
|
+
|
74
|
+
Then run specs by running
|
75
|
+
|
76
|
+
$ rake
|
77
|
+
|
50
78
|
## Contributing
|
51
79
|
|
52
80
|
1. Fork it ( https://github.com/[my-github-username]/pdfinfo/fork )
|
@@ -54,3 +82,8 @@ Pdfinfo.pdfinfo_command #=> '/another/bin/path/pdfinfo'
|
|
54
82
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
55
83
|
4. Push to the branch (`git push origin my-new-feature`)
|
56
84
|
5. Create a new Pull Request
|
85
|
+
|
86
|
+
## TODO
|
87
|
+
* Error handling
|
88
|
+
* type coersion is getting messy in initialize. refactor.
|
89
|
+
* Add #to_hash/#to_h/#as_json method to output all metadata as a hash
|
data/Rakefile
CHANGED
data/lib/pdfinfo.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'open3'
|
2
|
-
require 'pathname'
|
3
2
|
|
4
3
|
class Pdfinfo
|
5
|
-
DIMENSIONS_REGEXP = /(\d+) x (\d+)/
|
4
|
+
DIMENSIONS_REGEXP = /([\d\.]+) x ([\d\.]+)/
|
6
5
|
|
7
|
-
attr_reader :
|
6
|
+
attr_reader :title,
|
7
|
+
:subject,
|
8
|
+
:keywords,
|
9
|
+
:author,
|
10
|
+
:creator,
|
11
|
+
:creation_date,
|
12
|
+
:usage_rights,
|
8
13
|
:producer,
|
9
14
|
:form,
|
10
15
|
:page_count,
|
@@ -13,8 +18,15 @@ class Pdfinfo
|
|
13
18
|
:file_size,
|
14
19
|
:pdf_version
|
15
20
|
|
16
|
-
def self.exec(file_path)
|
17
|
-
|
21
|
+
def self.exec(file_path, opts = {})
|
22
|
+
flags = []
|
23
|
+
if opts[:owner_password]
|
24
|
+
flags << ['-opw', opts[:owner_password]]
|
25
|
+
elsif opts[:user_password]
|
26
|
+
flags << ['-upw', opts[:user_password]]
|
27
|
+
end
|
28
|
+
|
29
|
+
stdout, stderr, status = Open3.capture2e("#{pdfinfo_command} #{flags.join(" ")} #{file_path}")
|
18
30
|
stdout.chomp
|
19
31
|
end
|
20
32
|
|
@@ -26,15 +38,31 @@ class Pdfinfo
|
|
26
38
|
@pdfinfo_command = cmd
|
27
39
|
end
|
28
40
|
|
29
|
-
def initialize(source_path)
|
30
|
-
info_hash = parse_shell_response(Pdfinfo.exec(source_path))
|
41
|
+
def initialize(source_path, opts = {})
|
42
|
+
info_hash = parse_shell_response(Pdfinfo.exec(source_path, opts))
|
31
43
|
|
32
|
-
@
|
33
|
-
@
|
44
|
+
@title = info_hash['Title'].empty? ? nil : info_hash['Title']
|
45
|
+
@subject = info_hash['Subject'].empty? ? nil : info_hash['Subject']
|
46
|
+
@keywords = info_hash['Keywords'].empty? ? [] : info_hash['Keywords'].split(/\s/)
|
47
|
+
@author = info_hash['Author'].empty? ? nil : info_hash['Author']
|
48
|
+
@creator = info_hash['Creator'].empty? ? nil : info_hash['Creator']
|
49
|
+
@producer = info_hash['Producer'].empty? ? nil : info_hash['Producer']
|
50
|
+
@creation_date = info_hash['CreationDate'].empty? ? nil : Time.parse(info_hash['CreationDate'])
|
34
51
|
@tagged = !!(info_hash['Tagged'] =~ /yes/)
|
35
52
|
@form = info_hash['Form']
|
36
53
|
@page_count = info_hash['Pages'].to_i
|
37
54
|
@encrypted = !!(info_hash['Encrypted'] =~ /yes/)
|
55
|
+
|
56
|
+
raw_usage_rights = Hash[info_hash['Encrypted'].scan(/(\w+):(\w+)/)]
|
57
|
+
booleanize_usage_right = lambda {|val| !(raw_usage_rights[val] == 'no') }
|
58
|
+
|
59
|
+
@usage_rights = {}.tap do |ur|
|
60
|
+
ur[:print] = booleanize_usage_right.call('print')
|
61
|
+
ur[:copy] = booleanize_usage_right.call('copy')
|
62
|
+
ur[:change] = booleanize_usage_right.call('change')
|
63
|
+
ur[:add_notes] = booleanize_usage_right.call('addNotes')
|
64
|
+
end
|
65
|
+
|
38
66
|
@width, @height = extract_page_dimensions(info_hash['Page size'])
|
39
67
|
@file_size = info_hash['File size'].to_i
|
40
68
|
@pdf_version = info_hash['PDF version']
|
@@ -48,14 +76,30 @@ class Pdfinfo
|
|
48
76
|
@encrypted
|
49
77
|
end
|
50
78
|
|
51
|
-
|
79
|
+
def printable?
|
80
|
+
@usage_rights[:print]
|
81
|
+
end
|
52
82
|
|
83
|
+
def copyable?
|
84
|
+
@usage_rights[:copy]
|
85
|
+
end
|
86
|
+
|
87
|
+
def changeable?
|
88
|
+
@usage_rights[:change]
|
89
|
+
end
|
90
|
+
alias modifiable? changeable?
|
91
|
+
|
92
|
+
def annotatable?
|
93
|
+
@usage_rights[:add_notes]
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
53
97
|
def parse_shell_response(response_str)
|
54
|
-
Hash[response_str.split(/\n/).map {|kv| kv.split(
|
98
|
+
Hash[response_str.split(/\n/).map {|kv| kv.split(/:/, 2).map(&:strip) }]
|
55
99
|
end
|
56
100
|
|
57
101
|
def extract_page_dimensions(str)
|
58
102
|
return unless str
|
59
|
-
str.match(DIMENSIONS_REGEXP).captures.map(&:
|
103
|
+
str.match(DIMENSIONS_REGEXP).captures.map(&:to_f)
|
60
104
|
end
|
61
105
|
end
|
data/lib/pdfinfo/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
desc 'generates pdf for testing'
|
4
|
+
task :generate_fixtures do
|
5
|
+
class PdfGenerator
|
6
|
+
ROOT_DIR = File.expand_path("../../..", __FILE__)
|
7
|
+
METADATA_OPTIONS = {
|
8
|
+
Title: "Pdfinfo Title",
|
9
|
+
Author: "Pdfinfo Author",
|
10
|
+
Subject: "Pdfinfo Subject",
|
11
|
+
Keywords: "Keyword1 Keyword2",
|
12
|
+
Creator: "Pdfinfo Creator",
|
13
|
+
Producer: "Pdfinfo Producer",
|
14
|
+
CreationDate: Time.parse("2014-10-26 18:23:25 -0700")
|
15
|
+
}
|
16
|
+
ENCRYPTION_PERMISSIONS = {
|
17
|
+
print_document: false,
|
18
|
+
modify_contents: false,
|
19
|
+
copy_contents: false,
|
20
|
+
modify_annotations: false
|
21
|
+
}
|
22
|
+
ENCRYPTION_OPTIONS = {
|
23
|
+
user_password: 'foo',
|
24
|
+
owner_password: 'bar',
|
25
|
+
permissions: ENCRYPTION_PERMISSIONS
|
26
|
+
}
|
27
|
+
|
28
|
+
def self.generate(dest_path, opts = {})
|
29
|
+
new(opts).write_to(dest_path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(opts = {})
|
33
|
+
@encryption = opts[:encryption]
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param [String] dest_path path relative to gem root directory to write file to
|
37
|
+
def write_to(dest_path)
|
38
|
+
require 'prawn'
|
39
|
+
|
40
|
+
dest_path = File.join(ROOT_DIR, dest_path)
|
41
|
+
|
42
|
+
Prawn::Document.generate(dest_path, skip_page_creation: true, info: METADATA_OPTIONS, page_size: 'A4') do |pdf|
|
43
|
+
1.upto(5) do |n|
|
44
|
+
pdf.start_new_page
|
45
|
+
pdf.text("Page #{n}")
|
46
|
+
end
|
47
|
+
|
48
|
+
pdf.encrypt_document(ENCRYPTION_OPTIONS) if @encryption
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
PdfGenerator.generate("spec/fixtures/pdfs/test.pdf")
|
55
|
+
PdfGenerator.generate("spec/fixtures/pdfs/encrypted.pdf", encryption: true)
|
56
|
+
end
|
data/pdfinfo.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
20
|
spec.add_development_dependency "bundler", "~> 1.6"
|
21
|
-
spec.add_development_dependency "
|
21
|
+
spec.add_development_dependency "prawn"
|
22
|
+
spec.add_development_dependency "rspec", '~> 3.1.0'
|
22
23
|
spec.add_development_dependency "rake"
|
23
24
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Title: Pdfinfo Title
|
2
|
+
Subject: Pdfinfo Subject
|
3
|
+
Keywords: Keyword1 Keyword2
|
4
|
+
Author: Pdfinfo Author
|
5
|
+
Creator: Pdfinfo Creator
|
6
|
+
Producer: Pdfinfo Producer
|
7
|
+
CreationDate: Sun Oct 26 18:23:25 2014
|
8
|
+
Tagged: no
|
9
|
+
Form: none
|
10
|
+
Pages: 5
|
11
|
+
Encrypted: yes (print:no copy:no change:no addNotes:no)
|
12
|
+
Page size: 595.28 x 841.89 pts (A4) (rotated 0 degrees)
|
13
|
+
File size: 2861 bytes
|
14
|
+
Optimized: no
|
15
|
+
PDF version: 1.3
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Title: Pdfinfo Title
|
2
|
+
Subject: Pdfinfo Subject
|
3
|
+
Keywords: Keyword1 Keyword2
|
4
|
+
Author: Pdfinfo Author
|
5
|
+
Creator: Pdfinfo Creator
|
6
|
+
Producer: Pdfinfo Producer
|
7
|
+
CreationDate: Sun Oct 26 18:23:25 2014
|
8
|
+
Tagged: no
|
9
|
+
Form: none
|
10
|
+
Pages: 5
|
11
|
+
Encrypted: no
|
12
|
+
Page size: 595.28 x 841.89 pts (A4) (rotated 0 degrees)
|
13
|
+
File size: 2867 bytes
|
14
|
+
Optimized: no
|
15
|
+
PDF version: 1.3
|
data/spec/pdfinfo_spec.rb
CHANGED
@@ -1,20 +1,27 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Pdfinfo do
|
4
|
-
let(:pdf_path) { fixture_path('test.pdf') }
|
4
|
+
let(:pdf_path) { fixture_path('pdfs/test.pdf') }
|
5
5
|
let(:pdfinfo) { described_class.new(pdf_path) }
|
6
|
-
let(:
|
6
|
+
let(:encrypted_response) { File.read(fixture_path('shell_responses/encrypted.txt')).chomp }
|
7
|
+
let(:unencrypted_response) { File.read(fixture_path('shell_responses/test.txt')).chomp }
|
8
|
+
let(:mock_response) { unencrypted_response }
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
|
11
|
+
def modified_response(response, key, new_value = '')
|
12
|
+
response.sub(/(?<=#{key}:)(.+)$/, new_value)
|
13
|
+
end
|
14
|
+
|
15
|
+
specify "mock responses match" do
|
16
|
+
expect(`pdfinfo -upw foo #{fixture_path('pdfs/encrypted.pdf')}`.chomp).to eq(encrypted_response)
|
17
|
+
expect(`pdfinfo #{fixture_path('pdfs/test.pdf')}`.chomp).to eq(unencrypted_response)
|
11
18
|
end
|
12
19
|
|
13
20
|
before(:each) do
|
14
|
-
allow(
|
21
|
+
allow(Open3).to receive(:capture2e).and_return([mock_response, nil, nil])
|
15
22
|
end
|
16
23
|
|
17
|
-
describe 'pdfinfo_command' do
|
24
|
+
describe '.pdfinfo_command' do
|
18
25
|
it "falls back to pdfinfo" do
|
19
26
|
Pdfinfo.pdfinfo_command = nil
|
20
27
|
expect(Pdfinfo.pdfinfo_command).to eq('pdfinfo')
|
@@ -26,33 +33,128 @@ RSpec.describe Pdfinfo do
|
|
26
33
|
end
|
27
34
|
end
|
28
35
|
|
36
|
+
describe '.exec' do
|
37
|
+
context 'with no options given' do
|
38
|
+
it 'runs the pdfinfo command without flags' do
|
39
|
+
expect(Open3).to receive(:capture2e).with("pdfinfo path/to/file.pdf")
|
40
|
+
Pdfinfo.new("path/to/file.pdf")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "passing in :user_password" do
|
45
|
+
it 'runs the pdfinfo command passing the user password flag' do
|
46
|
+
expect(Open3).to receive(:capture2e).with("pdfinfo -upw foo path/to/file.pdf")
|
47
|
+
Pdfinfo.new("path/to/file.pdf", user_password: 'foo')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
context 'passing in :owner_password' do
|
51
|
+
it 'runs the pdfinfo command passing the user password flag' do
|
52
|
+
expect(Open3).to receive(:capture2e).with("pdfinfo -opw bar path/to/file.pdf")
|
53
|
+
Pdfinfo.new("path/to/file.pdf", owner_password: 'bar')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#title' do
|
59
|
+
context 'when given a title' do
|
60
|
+
it 'returns the title' do
|
61
|
+
expect(pdfinfo.title).to eq('Pdfinfo Title')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
context 'when title is not present' do
|
65
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Title', '') }
|
66
|
+
it 'returns nil' do
|
67
|
+
expect(pdfinfo.title).to be_nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#subject' do
|
73
|
+
context 'when given a subject' do
|
74
|
+
it 'returns the subject' do
|
75
|
+
expect(pdfinfo.subject).to eq('Pdfinfo Subject')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
context 'when title is not present' do
|
79
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Subject', '') }
|
80
|
+
it 'returns nil' do
|
81
|
+
expect(pdfinfo.subject).to be_nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#keywords' do
|
87
|
+
context 'when given keywords' do
|
88
|
+
it 'returns the keywords' do
|
89
|
+
expect(pdfinfo.keywords).to eq(['Keyword1', 'Keyword2'])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
context 'when keywords is not present' do
|
93
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Keywords', '') }
|
94
|
+
it 'returns an empty array' do
|
95
|
+
expect(pdfinfo.keywords).to eq([])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#author' do
|
101
|
+
context 'when given an author' do
|
102
|
+
it 'returns the author' do
|
103
|
+
expect(pdfinfo.author).to eq('Pdfinfo Author')
|
104
|
+
end
|
105
|
+
end
|
106
|
+
context 'when author is not present' do
|
107
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Author', '') }
|
108
|
+
it 'returns nil' do
|
109
|
+
expect(pdfinfo.author).to be_nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#creation_date' do
|
115
|
+
context 'when given an author' do
|
116
|
+
it 'returns a time object' do
|
117
|
+
expect(pdfinfo.creation_date).to be_an_instance_of(Time)
|
118
|
+
end
|
119
|
+
it 'returns the time correctly parsed' do
|
120
|
+
expect(pdfinfo.creation_date).to eq(Time.parse("2014-10-26 18:23:25 -0700"))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
context 'when creation date is not present' do
|
124
|
+
let(:mock_response) { modified_response(unencrypted_response, 'CreationDate', '') }
|
125
|
+
it 'returns nil' do
|
126
|
+
expect(pdfinfo.creation_date).to be_nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
29
131
|
describe '#creator' do
|
30
132
|
context 'when given a creator' do
|
31
|
-
it { expect(pdfinfo.creator).to eq('
|
133
|
+
it { expect(pdfinfo.creator).to eq('Pdfinfo Creator') }
|
32
134
|
end
|
33
135
|
context 'when creator is not present' do
|
34
|
-
let(:mock_response) {
|
136
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Creator', '') }
|
35
137
|
it { expect(pdfinfo.creator).to be_nil }
|
36
138
|
end
|
37
139
|
end
|
38
140
|
|
39
141
|
describe '#producer' do
|
40
142
|
context 'when given a creator' do
|
41
|
-
it { expect(pdfinfo.producer).to eq('
|
143
|
+
it { expect(pdfinfo.producer).to eq('Pdfinfo Producer') }
|
42
144
|
end
|
43
145
|
context 'when creator is not present' do
|
44
|
-
let(:mock_response) {
|
146
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Producer', '') }
|
45
147
|
it { expect(pdfinfo.producer).to be_nil }
|
46
148
|
end
|
47
149
|
end
|
48
150
|
|
49
|
-
describe 'tagged?' do
|
151
|
+
describe '#tagged?' do
|
50
152
|
context 'when tagged' do
|
51
|
-
let(:mock_response) {
|
153
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Tagged', 'yes') }
|
52
154
|
it { expect(pdfinfo.tagged?).to eq(true) }
|
53
155
|
end
|
54
156
|
context 'when not tagged' do
|
55
|
-
let(:mock_response) {
|
157
|
+
let(:mock_response) { modified_response(unencrypted_response, 'Tagged', 'no') }
|
56
158
|
it { expect(pdfinfo.tagged?).to eq(false) }
|
57
159
|
end
|
58
160
|
end
|
@@ -61,38 +163,118 @@ RSpec.describe Pdfinfo do
|
|
61
163
|
it { expect(pdfinfo.form).to eq('none') }
|
62
164
|
end
|
63
165
|
|
64
|
-
describe 'page_count' do
|
166
|
+
describe '#page_count' do
|
65
167
|
it 'returns a fixnum value of the number of pages' do
|
66
|
-
expect(pdfinfo.page_count).to eq(
|
168
|
+
expect(pdfinfo.page_count).to eq(5)
|
67
169
|
end
|
68
170
|
end
|
69
171
|
|
70
|
-
describe 'encrypted?' do
|
172
|
+
describe '#encrypted?' do
|
71
173
|
context 'given encrypted pdf' do
|
72
|
-
let(:mock_response) {
|
174
|
+
let(:mock_response) { encrypted_response }
|
73
175
|
it { expect(pdfinfo.encrypted?).to eq(true) }
|
74
176
|
end
|
75
177
|
context 'given unencrypted pdf' do
|
76
|
-
let(:mock_response) {
|
178
|
+
let(:mock_response) { unencrypted_response }
|
77
179
|
it { expect(pdfinfo.encrypted?).to eq(false) }
|
78
180
|
end
|
79
181
|
end
|
80
182
|
|
81
|
-
describe '
|
82
|
-
|
183
|
+
describe '#usage_rights' do
|
184
|
+
context 'given encrypted pdf (all flags off)' do
|
185
|
+
let(:mock_response) { encrypted_response }
|
186
|
+
it 'returns a permissions hash' do
|
187
|
+
expect(pdfinfo.usage_rights).to eq({
|
188
|
+
print: false,
|
189
|
+
copy: false,
|
190
|
+
change: false,
|
191
|
+
add_notes: false
|
192
|
+
})
|
193
|
+
end
|
194
|
+
end
|
195
|
+
context 'given unencrypted pdf' do
|
196
|
+
let(:mock_response) { unencrypted_response }
|
197
|
+
it 'returns a permissions hash' do
|
198
|
+
expect(pdfinfo.usage_rights).to eq({
|
199
|
+
print: true,
|
200
|
+
copy: true,
|
201
|
+
change: true,
|
202
|
+
add_notes: true
|
203
|
+
})
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
describe '#printable?' do
|
209
|
+
context 'given a pdf that is printable' do
|
210
|
+
let(:mock_response) { unencrypted_response }
|
211
|
+
it { expect(pdfinfo.printable?).to eq(true) }
|
212
|
+
end
|
213
|
+
context 'given a pdf that is not printable' do
|
214
|
+
let(:mock_response) { encrypted_response }
|
215
|
+
it { expect(pdfinfo.printable?).to eq(false) }
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#copyable?' do
|
220
|
+
context 'given a pdf that is copyable' do
|
221
|
+
let(:mock_response) { unencrypted_response }
|
222
|
+
it { expect(pdfinfo.copyable?).to eq(true) }
|
223
|
+
end
|
224
|
+
context 'given a pdf that is not copyable' do
|
225
|
+
let(:mock_response) { encrypted_response }
|
226
|
+
it { expect(pdfinfo.copyable?).to eq(false) }
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe '#changeable?' do
|
231
|
+
context 'given a pdf that is changeable' do
|
232
|
+
let(:mock_response) { unencrypted_response }
|
233
|
+
it { expect(pdfinfo.changeable?).to eq(true) }
|
234
|
+
end
|
235
|
+
context 'given a pdf that is not changeable' do
|
236
|
+
let(:mock_response) { encrypted_response }
|
237
|
+
it { expect(pdfinfo.changeable?).to eq(false) }
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe "#modifiable? (alias to changeable?)" do
|
242
|
+
context 'given a pdf that is changeable' do
|
243
|
+
let(:mock_response) { unencrypted_response }
|
244
|
+
it { expect(pdfinfo.modifiable?).to eq(true) }
|
245
|
+
end
|
246
|
+
context 'given a pdf that is not changeable' do
|
247
|
+
let(:mock_response) { encrypted_response }
|
248
|
+
it { expect(pdfinfo.modifiable?).to eq(false) }
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '#annotatable?' do
|
253
|
+
context 'given a pdf that is annotatable' do
|
254
|
+
let(:mock_response) { unencrypted_response }
|
255
|
+
it { expect(pdfinfo.annotatable?).to eq(true) }
|
256
|
+
end
|
257
|
+
context 'given a pdf that is not annotatable' do
|
258
|
+
let(:mock_response) { encrypted_response }
|
259
|
+
it { expect(pdfinfo.annotatable?).to eq(false) }
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe '#width' do
|
264
|
+
it { expect(pdfinfo.width).to eq(595.28) }
|
83
265
|
end
|
84
266
|
|
85
|
-
describe 'height' do
|
86
|
-
it { expect(pdfinfo.height).to eq(
|
267
|
+
describe '#height' do
|
268
|
+
it { expect(pdfinfo.height).to eq(841.89) }
|
87
269
|
end
|
88
270
|
|
89
|
-
describe 'size' do
|
271
|
+
describe '#size' do
|
90
272
|
it 'returns a fixnm value for the file size in bytes' do
|
91
|
-
expect(pdfinfo.file_size).to eq(
|
273
|
+
expect(pdfinfo.file_size).to eq(2867)
|
92
274
|
end
|
93
275
|
end
|
94
276
|
|
95
|
-
describe 'pdf_version' do
|
277
|
+
describe '#pdf_version' do
|
96
278
|
it 'returns a string value for the PDF spec version' do
|
97
279
|
expect(pdfinfo.pdf_version).to eq('1.3')
|
98
280
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pdfinfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Venegas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: prawn
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.1.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.1.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,6 +74,7 @@ extensions: []
|
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
62
76
|
- ".gitignore"
|
77
|
+
- ".rake_tasks~"
|
63
78
|
- ".rspec"
|
64
79
|
- ".ruby-gemset"
|
65
80
|
- ".ruby-version"
|
@@ -69,9 +84,10 @@ files:
|
|
69
84
|
- Rakefile
|
70
85
|
- lib/pdfinfo.rb
|
71
86
|
- lib/pdfinfo/version.rb
|
87
|
+
- lib/tasks/generate_pdf.rake
|
72
88
|
- pdfinfo.gemspec
|
73
|
-
- spec/fixtures/
|
74
|
-
- spec/fixtures/test.
|
89
|
+
- spec/fixtures/shell_responses/encrypted.txt
|
90
|
+
- spec/fixtures/shell_responses/test.txt
|
75
91
|
- spec/pdfinfo_spec.rb
|
76
92
|
- spec/spec_helper.rb
|
77
93
|
homepage: ''
|
@@ -99,7 +115,7 @@ signing_key:
|
|
99
115
|
specification_version: 4
|
100
116
|
summary: Simple ruby wrapper around the pdfinfo executable
|
101
117
|
test_files:
|
102
|
-
- spec/fixtures/
|
103
|
-
- spec/fixtures/test.
|
118
|
+
- spec/fixtures/shell_responses/encrypted.txt
|
119
|
+
- spec/fixtures/shell_responses/test.txt
|
104
120
|
- spec/pdfinfo_spec.rb
|
105
121
|
- spec/spec_helper.rb
|
data/spec/fixtures/test.pdf
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
%PDF-1.3
|
2
|
-
%����
|
3
|
-
1 0 obj
|
4
|
-
<< /Creator <feff0050007200610077006e>
|
5
|
-
/Producer <feff0050007200610077006e>
|
6
|
-
>>
|
7
|
-
endobj
|
8
|
-
2 0 obj
|
9
|
-
<< /Type /Catalog
|
10
|
-
/Pages 3 0 R
|
11
|
-
>>
|
12
|
-
endobj
|
13
|
-
3 0 obj
|
14
|
-
<< /Type /Pages
|
15
|
-
/Count 3
|
16
|
-
/Kids [5 0 R 8 0 R 10 0 R]
|
17
|
-
>>
|
18
|
-
endobj
|
19
|
-
4 0 obj
|
20
|
-
<< /Length 71
|
21
|
-
>>
|
22
|
-
stream
|
23
|
-
q
|
24
|
-
|
25
|
-
BT
|
26
|
-
36 747.384 Td
|
27
|
-
/F1.0 12 Tf
|
28
|
-
[<50> 120 <41> 30 <47452031>] TJ
|
29
|
-
ET
|
30
|
-
|
31
|
-
Q
|
32
|
-
|
33
|
-
endstream
|
34
|
-
endobj
|
35
|
-
5 0 obj
|
36
|
-
<< /Type /Page
|
37
|
-
/Parent 3 0 R
|
38
|
-
/MediaBox [0 0 612.0 792.0]
|
39
|
-
/Contents 4 0 R
|
40
|
-
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
41
|
-
/Font << /F1.0 6 0 R
|
42
|
-
>>
|
43
|
-
>>
|
44
|
-
>>
|
45
|
-
endobj
|
46
|
-
6 0 obj
|
47
|
-
<< /Type /Font
|
48
|
-
/Subtype /Type1
|
49
|
-
/BaseFont /Helvetica
|
50
|
-
/Encoding /WinAnsiEncoding
|
51
|
-
>>
|
52
|
-
endobj
|
53
|
-
7 0 obj
|
54
|
-
<< /Length 71
|
55
|
-
>>
|
56
|
-
stream
|
57
|
-
q
|
58
|
-
|
59
|
-
BT
|
60
|
-
36 747.384 Td
|
61
|
-
/F1.0 12 Tf
|
62
|
-
[<50> 120 <41> 30 <47452032>] TJ
|
63
|
-
ET
|
64
|
-
|
65
|
-
Q
|
66
|
-
|
67
|
-
endstream
|
68
|
-
endobj
|
69
|
-
8 0 obj
|
70
|
-
<< /Type /Page
|
71
|
-
/Parent 3 0 R
|
72
|
-
/MediaBox [0 0 612.0 792.0]
|
73
|
-
/Contents 7 0 R
|
74
|
-
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
75
|
-
/Font << /F1.0 6 0 R
|
76
|
-
>>
|
77
|
-
>>
|
78
|
-
>>
|
79
|
-
endobj
|
80
|
-
9 0 obj
|
81
|
-
<< /Length 71
|
82
|
-
>>
|
83
|
-
stream
|
84
|
-
q
|
85
|
-
|
86
|
-
BT
|
87
|
-
36 747.384 Td
|
88
|
-
/F1.0 12 Tf
|
89
|
-
[<50> 120 <41> 30 <47452033>] TJ
|
90
|
-
ET
|
91
|
-
|
92
|
-
Q
|
93
|
-
|
94
|
-
endstream
|
95
|
-
endobj
|
96
|
-
10 0 obj
|
97
|
-
<< /Type /Page
|
98
|
-
/Parent 3 0 R
|
99
|
-
/MediaBox [0 0 612.0 792.0]
|
100
|
-
/Contents 9 0 R
|
101
|
-
/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
102
|
-
/Font << /F1.0 6 0 R
|
103
|
-
>>
|
104
|
-
>>
|
105
|
-
>>
|
106
|
-
endobj
|
107
|
-
xref
|
108
|
-
0 11
|
109
|
-
0000000000 65535 f
|
110
|
-
0000000015 00000 n
|
111
|
-
0000000109 00000 n
|
112
|
-
0000000158 00000 n
|
113
|
-
0000000228 00000 n
|
114
|
-
0000000349 00000 n
|
115
|
-
0000000527 00000 n
|
116
|
-
0000000624 00000 n
|
117
|
-
0000000745 00000 n
|
118
|
-
0000000923 00000 n
|
119
|
-
0000001044 00000 n
|
120
|
-
trailer
|
121
|
-
<< /Size 11
|
122
|
-
/Root 2 0 R
|
123
|
-
/Info 1 0 R
|
124
|
-
>>
|
125
|
-
startxref
|
126
|
-
1223
|
127
|
-
%%EOF
|